2014-12-02 60 views
3

是否可以獲取序列化協議緩衝區消息的類型?Google協議緩衝區,如何處理多個消息類型?

我有這樣的例子

option java_outer_classname="ProtoUser"; 

message User { 
    required int32 id = 1; 
    required string name = 2; 
    required string firstname = 3; 
    required string lastname = 4; 
    required string ssn= 5; 
} 

message Address { 
    required int32 id = 1; 
    required string country = 2 [default = "US"];; 
    optional string state = 3; 
    optional string city = 4; 
    optional string street = 5; 
    optional string zip = 6; 
} 

在Java中我有這樣的代碼

Address addr = ProtoUser.Address.newBuilder().setCity("Weston").setCountry("USA").setId(1).setState("FL").setStreet("123 Lakeshore").setZip("90210") 
      .build(); 

    User user = ProtoUser.User.newBuilder().setId(1).setFirstname("Luis").setLastname("Atencio").setName("luisat").setSsn("555-555-5555").build(); 

if(....){ 
    FileOutputStream output = new FileOutputStream("out1.ser"); 
    user.writeTo(output); 
    output.close(); 
}else{ 
    FileOutputStream output = new FileOutputStream("out1.ser"); 
    addr.writeTo(output); 
    output.close(); 
} 

現在,我能確定,如果該文件包含地址還是用戶?處理多種消息類型的常用方法是什麼?我如何確定我收到的消息類型?

回答

5

我們無法確定文件是否包含地址或用戶。因爲數據中沒有編碼的類型信息。

要處理多個消息類型,可以使用元數據,如:在HTTP在框架基座流協議

    • 擴展的文件名
    • 接頭連接
    • 具體幀頭.. 。
  • +0

    好吧,這只是一個例子。我將在稍後通過TCP和Unix套接字發送序列化的字符串。可能是像發送'CommandX;'+ serializedString一個很好的解決方案? – user2071938 2014-12-02 12:01:38

    +0

    是的。在框架頭部放置一些元數據來描述下面的有效載荷。 – Dante 2014-12-02 13:05:37

    +4

    @ user2071938可以將所有消息包裝在公共容器消息中(全部爲「可選」或與新的「oneof」聯合構造:https://developers.google.com/protocol-buffers/docs/proto#oneof) - 這與在protobuf級別添加標題基本相同。 – zapl 2014-12-02 13:33:19

    1

    要麼你:

    1. 包括信息這是否是一個地址或名稱的文件結尾(如果文件只包含一種類型在一個時間)
    2. 明確指定數據包的類型的序列化形式,即增加一個字段required int32 type並從該字段中推斷出該類型。 (如果兩種類型一次包含在一個文件中)
    3. 設計明確包含此信息的特定外部消息格式幷包裝協議緩衝區。

    無論哪種方式合適,如果您將它們複用到一個通道上 - 您通過選擇相同的文件結尾來完成 - 您必須在收到它們時再次解複用它們。