43
votes

I'm refactoring legacy C++ system to SOA using gSoap. We have some performance issues (very big XMLs) so my lead asked me to take a look at protocol buffers. I did, and it looks very cool (We need C++ and Java support). However protocol buffers are solution just for serialization and now I need to send it to Java front-end. What should I use from C++ and Java perspective to send those serialized stuff over HTTP (just internal network)?

PS. Another guy tries to speed-up our gSoap solution, I'm interested in protocol buffers only.

5
FYI. the performance was discussed with the gsoap team (I participate in this) and we recommended to use the SOAP_XML_TREE flag or compile with -DWITH_NOIDREF. Without this flag the performance can be much lower because of the SOAP encoding with multi-ref elements (id-ref) to serialize graphs (i.e. detect co-referenced objects, analyze cyclic data structures, etc). The suggested flag turns this feature off to serialize XML as trees. Messaging speed is greatly improved. The only bottleneck to performance is network latency and bandwidth.Dr. Alex RE
@Alex SOAP is still getting updated? That's actually impressive! That question is 7 years old so not gonna act on that :)Nazgob
From what I learned everyone else has read the FAQ (since 2005) with this recommendation. What makes you believe this is a recent development?Dr. Alex RE
@alex I did not read that FAQ so your argument can't be true, clearly not everybody have read it. Its also irrelevant as I stated that I was only interested in protocol buffers.Nazgob

5 Answers

64
votes

You can certainly send even a binary payload with an HTTP request, or in an HTTP response. Just write the bytes of the protocol buffer directly into the request/response, and make sure to set the content type to "application/octet-stream". The client, and server, should be able to take care of the rest easily. I don't think you need anything more special than that on either end.

25
votes

ProtoBuf is a binary protocol. It doesn't mix well with SOAP. I suggest you either stick with gSOAP or convert to ProtoBuf entirely.

With protoBuf, you define your protocol in a special format like this,

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

The protoc tool can generate code in C++/Java/Python so you can serialize it on one end and deserialize on another.

As you can see, ProtoBuf is designed to serialize individual object. It doesn't provide all the facilities provided by SOAP, like headers. To get around this issue, we use ProtoBuf inside ProtoBuf. We define an Envelope like this,

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 is another serialized ProtoBuf message. All the stuff in SOAP header now goes to headers.

9
votes

Google frontends prefer application/protobuf.

The ProtocolBufferModel of the Google API client uses application/x-protobuf.

7
votes

You can serialize/de-serialize protobuf encoded data to/from strings. Send the serialized string as the body of an HTTP POST to Java and de-serialize it. That is one approach. Another way is to make use of the protobuf Service interface. Protobuf allows you to define a service interface in a .proto file and the protocol buffer compiler will generate service interface code and stubs in your chosen language. You only need to implement the protobuf::RpcChannel and protobuf::RpcController classes to get a complete RPC framework. Probably you can write an HTTP wrapper for these classes. See the following links for more information:

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

2
votes

To my knowledge protocol buffers support is available in both C++ and Java, you should be able to exchange protocol buffer serialized data between both systems.

That said, it seems your real question is "How do I send stuff over HTTP between a C++ backend and Java client"

It sound like you need to learn how to use gSOAP, read the docs.

Alternatively you could host a RESTful web server from your C++ app: Look at this: https://stackguides.com/questions/298113/how-can-i-implement-a-restful-webservice-using-c++

Next you would need to access the data hosted on your new C++ RESTful server: Look at this: Rest clients for Java?