Java 谷歌协议缓冲区,如何处理多种消息类型?

Java 谷歌协议缓冲区,如何处理多种消息类型?,java,protocol-buffers,Java,Protocol Buffers,是否可以获取序列化协议缓冲区消息的类型 我有这个例子 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; } messag

是否可以获取序列化协议缓冲区消息的类型

我有这个例子

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();
}

现在,我可以确定该文件是否包含地址或用户吗?处理多种消息类型的常用方法是什么?如何确定收到的邮件类型?

我们无法确定文件是否包含地址或用户。因为数据中没有编码的类型信息

要处理多种消息类型,可以使用元数据,如:

  • 文件名的扩展名
  • HTTP中的头文件
  • 帧基流协议中的特定帧头
您可以:

  • 在文件结尾处包含地址或名称的信息(如果文件一次只包含一种类型)
  • 以序列化形式明确指定数据包的类型,即添加一个字段
    required int32 type
    ,并从该字段推断类型。(如果两种类型一次包含在一个文件中)
  • 设计明确包含此信息的特定外部消息格式,并包装协议缓冲区

  • 无论哪种情况合适,如果将它们多路复用到一个通道上(通过选择相同的文件结尾来实现),则在接收到它们时必须再次将其解复用。

    好的,这只是一个示例。稍后我将通过TCP和Unix套接字发送序列化字符串。可能类似于发送“CommandX;”+找到一个好的解决方案吗?是的。将一些元数据放在帧的头部以描述以下有效负载。@user2071938您可以将所有消息包装在一个公共容器消息中(所有
    可选
    或使用新的
    联合构造之一:)-这基本上与在protobuf级别添加头相同。同意@zapl.:-)另请参见文档的这一部分,尽管它显然尚未更新以利用2.6.0中新的
    oneof
    功能: