我现在正在使用谷歌协议缓冲区并有一个问题。如果我有多个.proto文件,因此有多个类,是否可以通过套接字发送数据以确定它是哪种类型?
E.g。我有两个类,我们称之为person.proto和adress.proto。现在我通过电汇发送其中一个。接收者如何确定它是人还是地址?
我在C ++中这样做。
我的尝试是在消息周围添加一个框架,其中包含长度和类型。但我想知道是否已经有类型的东西的某种实现,所以我不重新实现现有的东西。
答案 0 :(得分:2)
是的,这是可能的。 Protobuf使用所谓的message descriptors支持反射。
但是(如另一个答案所述)你需要一个可靠的众所周知的根消息类型。恕我直言,不是引入自己的信息识别机制,而是使用protobufs extension mechanism
以下是我们生产中的样本
package Common.ConfigurationCommands;
message UcpConfiguration
{
optional uint32 componentIndex = 1;
optional ConfigCmdStatus configCmdResponseStatus = 2;
optional string configErrorDescription = 3;
extensions 100 to max;
}
扩展名如
import "Common/ConfigurationCommands.proto";
message AmplifierConfiguration
{
extend Common.ConfigurationCommands.UcpConfiguration
{
optional AmplifierConfiguration amplifierConfiguration = 108;
}
optional uint32 preemphasis = 1;
}
import "Common/ConfigurationCommands.proto";
message FrontendConfiguration
{
extend Common.ConfigurationCommands.UcpConfiguration
{
optional FrontendConfiguration frontendConfiguration = 100;
}
optional bool frontendActive = 1;
optional uint32 refInputComponentIndex = 2;
extensions 100 to max;
}
您可以查看this part of the documentation,了解如何处理C ++代码中的扩展程序。
答案 1 :(得分:1)
无法检测哪个对象被序列化,Protobuf不会这样做。但你可以很容易地使用protobuf处理它:
1)方法:只发送包含类型和字符串主体的消息。对于正文,您将序列化对象,在类型中,您将显示序列化的对象:
类似的东西:
package MyGreatPackage;
message Pack
{
required bytes packcode = 1;
//code for data/query
required bytes mess = 2;
}
message Data
{
//anything you need to
}
message Query
{
//anything you need to
}
因此,您将始终发送消息包,其中将定义哪个对象完全位于" mess"字段。
2)方法: protobuf允许这种技术在没有包装器的情况下实现相同的功能,请看这里:https://developers.google.com/protocol-buffers/docs/techniques?hl=ru#union
message OneMessage {
enum Type { FOO = 1; BAR = 2; BAZ = 3; }
// Identifies which field is filled in.
required Type type = 1;
// One of the following will be filled in.
optional Foo foo = 2;
optional Bar bar = 3;
optional Baz baz = 4;
}
因此,您可以将可能发送的所有类设置为可选,并根据所需参数确定其类型。
不过,对我来说,第一个varians似乎更好,选择你喜欢的。