2009-09-15 10 views
34

gSoapを使用して従来のC++システムをSOAにリファクタリングしています。私はいくつかのパフォーマンス上の問題(非常に大きなXML)を持っていましたので、私の指導のもとにプロトコルバッファを調べるように求めました。私はやった、それは非常にクールに見える(私たちはC + +とJavaのサポートが必要)。しかし、プロトコルバッファは単にシリアライゼーション用のソリューションであり、今ではJavaフロントエンドに送る必要があります。これらのシリアル化されたものをHTTP(単に内部ネットワーク)経由で送信するには、C++とJavaの観点から何を使用する必要がありますか?GoogleプロトコルバッファとHTTP

PS。別の人が私たちのgoSoapソリューションのスピードアップを試みています。私はプロトコルバッファだけに興味があります。

+0

FYI。パフォーマンスはgsoapチームと議論されました(私はこれに参加しました)。そして、 'SOAP_XML_TREE'フラグを使うか、' -DWITH_NOIDREF'でコンパイルすることを推奨しました。このフラグがなければ、グラフをシリアライズする(つまり、相互参照されたオブジェクトを検出し、周期的なデータ構造を分析する)ために、複数のref要素(id-ref)でSOAPエンコーディングするため、パフォーマンスが大幅に低下する可能性があります。提案されたフラグはXMLをツリーとしてシリアライズするためにこの機能をオフにします。メッセージング速度が大幅に向上しました。パフォーマンスの唯一のボトルネックは、ネットワークの待ち時間と帯域幅です。 –

+0

@Alex SOAPはまだ更新されていますか?それは実際に印象的です!その質問は7歳ですので、そのことに気付かないでしょう:) – Nazgob

+0

私が他の人に知っていることは、この勧告でFAQ(2005年以降)を読んだことです。これが最近の発展であると思わせる原因は何ですか? –

答えて

53

HTTPリクエストを使用してバイナリペイロードを送信することも、HTTPレスポンスを送信することもできます。リクエスト/レスポンスにプロトコルバッファのバイトを直接書き込んで、コンテンツタイプを "application/octet-stream"に設定してください。クライアントとサーバーは、残りの部分を簡単に処理できるはずです。私はどちらかというと、それよりも特別なものは必要ないと思う。

+30

ここでスライド21で説明した 'application/x-protobuf'を使っています:http://www.slideshare.net/mokeefe/javaone-2009-ts5276-restful-protocol-buffers –

+0

ああ、誰かがMIMEタイプを提案しているのを知らなかった。 –

+5

"x-"で始まる名前を持つMIMEタイプはどこにもありません。通常、application/octet-streamとして扱われます。 – n0rd

2

私の知る限り、プロトコルバッファのサポートはC++とJavaの両方で利用できます。両方のシステム間でプロトコルバッファのシリアル化されたデータを交換できる必要があります。言っ

は、あなたの本当の問題は、「私はC++バックエンドとJavaクライアントの間でHTTP経由でものを送るにはどうすればよい」

あなたがのgSOAPを使用する方法を学習する必要があるように聞こえる、docsを読んでいるようです。

また、あなたのC++アプリからのRESTful Webサーバーをホストする可能性があります:これを見て:https://stackoverflow.com/questions/298113/how-can-i-implement-a-restful-webservice-using-c++

次のあなたの新しいC++ RESTfulなサーバー上でホストされているデータにアクセスする必要があります。これを見て:Rest clients for Java?

+2

gSOAPはこの問題を大幅に克服しています。 Protobufsはネイティブのバイナリ形式でHTTP上で正常に動作します。 – Will

+0

複雑すぎる?もちろん、バイナリコンテンツを転送する場合は、ProtobufsとRESTを使用してください。しかしXMLのために、私たちの仕事はずっと楽になりました。 WSDL、SOAP、XMLの複雑な部分はすべて世話をしています。また、gsoapを使用して、毎秒5,000件以上のサービス呼び出しを取得しました。主なオーバーヘッドはTCP/IPであり、gsoapスタックではありません。 –

5

protobufエンコードされたデータを文字列にシリアル化/デシリアライズすることができます。シリアライズされた文字列をHTTP POSTの本体としてJavaに送信し、逆シリアル化します。それが一つのアプローチです。別の方法は、protobufサービスインターフェイスを使用することです。 Protobufでは、.protoファイルにサービスインタフェースを定義することができ、プロトコルバッファコンパイラは、選択した言語でサービスインタフェースコードとスタブを生成します。完全なRPCフレームワークを取得するには、protobuf :: RpcChannelクラスとprotobuf :: RpcControllerクラスを実装する必要があります。おそらく、これらのクラスの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で

、あなたは一端に、それをシリアル化し、別の上にデシリアライズすることができますので、protocツールはC++/Javaの/ Pythonでコードを生成することができ

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

、このような特別な形式でのプロトコルを定義します。

ご覧のとおり、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; 
} 

encodedMessage

は別のシリアル化されいるProtobufメッセージであり、このように封筒を定義します。SOAPヘッダーの内容はすべて headersになります。

4

Googleのフロントエンドはapplication/protobufです。

Google APIクライアントのProtocolBufferModelにはapplication/x-protobufが使用されています。

関連する問題