3

送信されているprotobufメッセージの種類を知るためのAPIは何ですか?

たとえば、次を使用して SendNameMessage オブジェクトを取得します。

SendNameMessage sendNameObj = Serializer.DeserializeWithLengthPrefix< SendNameMessage>(ストリーム, PrefixStyle.Fixed32);

リスナーは、送信されているメッセージの種類をどのように知ることができますか?

以下は私の SendNameMessage クラスです:

[ProtoContract]
class SendNameMessage
{
    [ProtoMember(1)]
    public string sendName { get; set; }

    [ProtoMember(2)]
    public int sendId { get; set; }
}

送信されたメッセージが sendName か sendId かを知るにはどうすればよいですか?

4

1 に答える 1

3

protobuf (任意の実装で) は単なるシリアライゼーション API です。ネットワーク上で話している場合、デフォルトでは、両端でデータが何であるかがすでに合意されています。さまざまな種類のメッセージを送信するために、いくつかのオプションが表示されます。

  1. さまざまなメッセージ タイプを表す子オブジェクトを単に持つラッパー オブジェクトがあります。特にprotobuf-netを使用すると、これを継承に直接マップすることもできます(protobuf-netは継承をカプセル化にマップするため)
  2. メッセージヘッダーを使用します-これを識別するメッセージの前のある種のデータ。特に、Base128プレフィックス スタイルを使用している場合は、メッセージと共に送信されるフィールド番号を含めることができます (デフォルトは1ですが、オーバーロードされたメソッドを使用すると、これを指定できます)。Serializer.NonGeneric.TryDeserializeWithLengthPrefix次に、フィールド番号から型解決を実行するデリゲート パラメーターを含む方法でこれを逆シリアル化します。

編集後... と に言及sendIdsendNameましたが、メッセージSendNameMessageです。そのメッセージでは、常にすべて (デフォルトを除く) になります。それは両方かもしれません。どちらでもない。したがって、そのシナリオでは、それを逆シリアル化してチェック.sendNameし、.sendId.

ここでのもう1 つの一般的なオプションは、おそらく単に列挙型のdiscriminatorを追加することです。

enum MesageType {
    Error = 0,
    Name = 1,
    Id = 2
}

メッセージにそれを含めます:

[ProtoMember(10)]
public MessageType MessageType {get;set;}

これで、メッセージ タイプの意味を明示的に表現する方法が得られました。

于 2010-07-12T22:18:17.177 に答える