简而言之,有没有办法定义一个包含另一个任意类型消息的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;
}
这是实现这一目标的唯一方法吗?
答案 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;
}
}