2009-09-15 7 views
34

Я перестраиваю устаревшую систему C++ на SOA с помощью gSoap. У нас есть некоторые проблемы с производительностью (очень большие XML-файлы), поэтому мое руководство попросило меня взглянуть на буферы протокола. Я сделал, и это выглядит очень круто (нам нужны поддержка на C++ и Java). Однако буферы протокола - это решение только для сериализации, и теперь мне нужно отправить его в интерфейс Java. Что я должен использовать с точки зрения C++ и Java для отправки этих сериализованных данных через HTTP (только внутренняя сеть)?Буферы протокола Google и HTTP

PS. Другой парень пытается ускорить решение gSoap, меня интересуют только протокольные буферы.

+0

FYI. производительность обсуждалась с командой gsoap (я участвую в этом), и мы рекомендовали использовать флаг SOAP_XML_TREE или компилировать с помощью '-DWITH_NOIDREF'. Без этого флага производительность может быть намного ниже из-за SOAP-кодирования с элементами multi-ref (id-ref) для сериализации графиков (т. Е. Обнаружения объектов со ссылкой, анализа циклических структур данных и т. Д.). Предлагаемый флаг отключает эту функцию для сериализации XML как деревьев. Скорость обмена сообщениями значительно улучшена. Единственным недостатком производительности является латентность сети и пропускная способность. –

+0

@Alex SOAP все еще обновляется? Это действительно впечатляет! Этот вопрос составляет 7 лет, поэтому не собираюсь действовать на это :) – Nazgob

+0

Из того, что я узнал, все остальные прочитали FAQ (с 2005 года) с этой рекомендацией. Почему вы считаете, что это недавняя разработка? –

ответ

53

Вы можете отправить даже двоичную полезную нагрузку с помощью HTTP-запроса или ответа HTTP. Просто напишите байты буфера протокола непосредственно в запросе/ответе и не забудьте установить тип содержимого «application/octet-stream». Клиент и сервер должны иметь возможность позаботиться об остальном легко. Я не думаю, что вам нужно что-то более особенное, чем с обеих сторон.

+30

Мы используем 'application/x-protobuf', как описано на слайде 21 здесь: http://www.slideshare.net/mokeefe/javaone-2009-ts5276-restful-protocol-buffers –

+0

А еще лучше. Не знал, что кто-то предложил тип MIME для этого. –

+5

Типы MIME, имеющие имя, начинающееся с «x-», нигде не приближаются к стандарту и обычно рассматриваются как приложение/октет-поток. – n0rd

2

Насколько я знаю, поддержка буферов протокола доступна как на C++, так и на Java, вы должны иметь возможность обмениваться последовательными данными буфера протокола между обеими системами.

Тем не менее, это, кажется, ваш реальный вопрос: «Как я могу отправить вещи через HTTP между ++ бэкэндом C и клиент Java»

Это звучит, как вам нужно, чтобы узнать, как использовать gSOAP, читать docs.

В качестве альтернативы вы можете провести RESTful веб-сервер от вашего приложения C++: Посмотрите на это: https://stackoverflow.com/questions/298113/how-can-i-implement-a-restful-webservice-using-c++

Далее вам необходимо будет получить доступ к данным, размещенным на RESTful сервере вашего нового C++: Посмотрите на это: Rest clients for Java?

+2

gSOAP сильно нарушает проблему. Protobufs отлично работают над HTTP в своем двоичном формате. – Will

+0

Сложный? Конечно, если вы хотите передать двоичный контент, просто используйте Protobufs и REST. Но для XML это упростило нашу работу. Сложные части WSDL, SOAP и XML все позаботились. Кроме того, мы получили более 5000 вызовов службы в секунду с помощью gsoap. Основные накладные расходы связаны с TCP/IP, а не с пакетом gsoap. –

5

Вы можете сериализовать/де-сериализовать закодированные данные protobuf в/из строк. Отправьте сериализованную строку как тело HTTP POST на Java и де-сериализуйте его. Это один из подходов. Другой способ - использовать интерфейс службы protobuf. Protobuf позволяет вам определить интерфейс службы в файле .proto, а компилятор буфера протокола будет генерировать код интерфейса и заглушки на выбранном вами языке. Вам нужно всего лишь реализовать классы protobuf :: RpcChannel и protobuf :: RpcController, чтобы получить полную инфраструктуру RPC. Вероятно, вы можете написать HTTP-обертку для этих классов. Смотрите следующие ссылки для получения дополнительной информации:

http://code.google.com/apis/protocolbuffers/docs/proto.html#services http://code.google.com/apis/protocolbuffers/docs/reference/cpp-generated.html#service http://code.google.com/apis/protocolbuffers/docs/reference/cpp/google.protobuf.service.html

24

Protobuf является двоичным протоколом. Он не очень хорошо сочетается с SOAP. Я предлагаю вам либо использовать gSOAP, либо полностью конвертировать в ProtoBuf.

С Protobuf, вы определяете свой протокол в специальном формате, как это,

message Product { 
    required string id = 1; 
    required string description = 2; 
    required int32 quantity = 3; 
    optional bool discontinued = 4; 
} 

Инструмент protoc может генерировать код на C++/Java/Python, так что вы можете сериализовать его на одном конце и десериализации на другой.

Как вы можете видеть, ProtoBuf предназначен для сериализации отдельного объекта. Он не предоставляет все средства, предоставляемые SOAP, например, заголовки. Чтобы обойти эту проблему, мы используем ProtoBuf внутри ProtoBuf. Определим конверт, как это,

message Envelope { 
    enum Type { 
    SEARCH = 1; 
    SEARCH_RESPONSE = 2; 
    RETRIEVE = 3; 
    RETRIEVE_RESPONSE = 4; 
    } 
    required Type type = 1; 

    required bytes encodedMessage = 2; 

    message Header { 
    required string key = 1; 
    required bytes value = 2; 
    }  
    repeated Header headers = 3; 
} 

The encodedMessage еще один сериализованная Protobuf сообщение.Все материалы в заголовке SOAP теперь идут до headers.

4

Привилегии Google предпочитают application/protobuf.

ProtocolBufferModel клиента Google API использует application/x-protobuf.