Protobuf:嵌套任意类型的消息

时间:2012-08-30 08:03:41

标签: protocol-buffers

简而言之,有没有办法定义一个包含另一个任意类型消息的protobuf消息?类似的东西:

message OuterMsg {
    required int32 type = 1;
    required Message nestedMsg = 2; //Any sort of message can go here
}

我怀疑有一种方法可以做到这一点,因为在各种protobuf实现中,编译的消息从公共Message基类扩展。

否则我想我必须为各种类型的消息创建一个公共基本消息:

message BaseNestedMessage {
    extensions 1 to max;
}

然后再做

message OuterMessage {
    required int32 type = 1;
    required BaseNestedMessage nestedMsg = 2;
}

这是实现这一目标的唯一方法吗?

3 个答案:

答案 0 :(得分:8)

最常用的方法是为每种消息类型创建可选字段:

message UnionMessage
{
    optional MsgType1 msg1 = 1;
    optional MsgType2 msg2 = 2;
    optional MsgType3 msg3 = 3;
}

此技术也在官方Google文档中进行了描述,并且在各种实现中得到了很好的支持: https://developers.google.com/protocol-buffers/docs/techniques#union

答案 1 :(得分:6)

基本上不直接;协议缓冲区非常想提前知道结构,并且线路上 类型不包含在 中。公共Message基类是用于提供常见管道代码的实现细节 - 协议缓冲区规范不包括继承。

因此,选择有限:

  • 每个消息类型使用不同的字段编号
  • 单独序列化邮件,并将其包含为bytes类型,并传达“这是什么?”信息分开(大概是鉴别者/枚举)

我还应该注意,某些实现可能为此提供更多支持; protobuf-net(C#/ .NET)支持(单独)继承和动态消息类型(即上面提到的内容), 主要仅供使用从那个图书馆到那个图书馆。因为除了规范之外,这都是(在有线格式方面保持100%有效),从其他实现中解释这些数据可能会造成不必要的麻烦。

答案 2 :(得分:1)

除了optional的v2.6之外,我还可以使用oneof关键字替代多个Protocol Buffers字段。

message UnionMessage {
  oneof data {
    string a = 1;
    bytes b = 2;
    int32 c = 3;
  }
}