7

私は現在、プロジェクトで使用するプロトコル バッファを評価しています (まだコードは書かれていません)。私が不明なことの 1 つは、エンコードされたメッセージの一部をどのように読み取るかということです。たとえば、共通のヘッダーがあるとします。

message Header {
  required uint16 msg_type = 1;
  required uint16 length = 2;
}

そして、複数の異なるメッセージをキューに配信するとします。コンシューマーは、メッセージごとに読み取るデータの量と、どのメッセージ タイプを構築する必要があるかをどのように判断しますか?

4

3 に答える 3

4

Headerここにメッセージは必要ありません。最も一般的なアプローチは、ここからの「ストリーミング」のアドバイスに従うことです。その中で、それを一連の同一の共用体タイプのメッセージとして扱うか、(私の好み) 書くときに、それぞれの前に長さプレフィックスを書くだけでなく、メッセージのタイプと長さを示す varint を含めます(ヴァリント)。メッセージ タイプを示す数字は、作成した任意のマップです。つまり、1 = Foo、2 = Bar、3 = Blap などです)。message-type を 3 ビット左シフトしてから「or」2 にすると、それ自体も整形式の protobuf ストリームになり、a と100% 同一になりrepeated YourUnionTypeます。

基本的に、これはこの answerとまったく同じですが、毎回フィールド 1 ではなく、メッセージ タイプごとに数が異なります。ほとんどの実装には、生の varint の読み取りと書き込み、およびリーダー API の長さ制限を可能にするリーダー/ライター API があります。一部の実装には、異種メッセージのストリームを直接サポートするヘルパー メカニズムがあります (基本的に、上記のすべてを自動的に実行します)。

于 2012-11-13T14:52:10.070 に答える
2

最近のプロジェクトでは、次のように Protocol Buffers を使用しました。

オプションのメンバーとしてすべての実際のメッセージを含む 1 つの「コンテナー」メッセージがありました。

message ContainerMessage {
    optional Message1 message_1 = 1;
    optional Message2 message_2 = 2;
    //...
    optional MessageN message_N = N;
}

ContainerMessageアプリケーション内では、実際のメッセージの識別結合として使用できます。

アプリケーション間で、 をシリアル化/逆シリアル化し、シリアルContainerMessage化されたコンテンツの長さを含む単純なヘッダーを前に付けて、シリアル化されたコンテンツを送信しました。

于 2012-11-13T16:20:39.720 に答える
0

これは、使用しているプロトコルによって異なります。

たとえば、多くのプロトコルがシリアル インターフェイスを介して行われることに注意してください。この場合、メッセージの開始と停止を伝える余分な行が含まれる場合があります。

多くの場合、メッセージは、メッセージの開始後に固定オフセットで長さを持ちます。

また、メッセージを要素ごとに解析して、残っているメッセージの量を調べる必要がある場合もあります。したがって、メッセージに埋め込まれた文字列は、固定長であったり、先頭に長さがあったり、終了マーカーとして \0 があったりします。

ほとんどの場合、さらに処理するためにメッセージをキューに保存する場合、作業を楽にするために情報を追加する必要があります。長さ。

于 2012-11-13T14:58:19.493 に答える