Protocol buffers 如何判断序列化协议缓冲区中的消息类型?
我原以为每次尝试Protocol buffers 如何判断序列化协议缓冲区中的消息类型?,protocol-buffers,Protocol Buffers,我原以为每次尝试parseFrom(bytes)时,当我不使用预期的消息类时,会得到一个InvalidProtocolBufferException 我的代码如下所示: try { LoginMessage msg = LoginMessage.parseFrom(bytes); // ... use msg ... } catch(InvalidProtocolBufferException exception) { ErrorMessage error = Er
parseFrom(bytes)
时,当我不使用预期的消息类时,会得到一个InvalidProtocolBufferException
我的代码如下所示:
try {
LoginMessage msg = LoginMessage.parseFrom(bytes);
// ... use msg ...
} catch(InvalidProtocolBufferException exception) {
ErrorMessage error = ErrorMessage.parseFrom(bytes);
// ... do something ...
}
我的信息如下:
message LoginMessage
{
required Status status = 1;
optional UserMessage user= 2;
}
message ErrorMessage
{
required Error error = 1;
}
其中TeamStatus
和Error
是枚举
当我执行应该产生ErrorMessage
的代码时,它将解析为LoginMessage
,并将两个枚举:error
字段与status
字段混淆
那么我如何区分这两种类型的信息呢
它似乎使用结构类型进行优化,因此不传输字段名或消息类型,但解决此问题的实际方法是什么?我不想在登录消息
中插入错误消息
,而总是返回登录消息
我考虑将
error
字段索引设置为其他消息不会使用的数字,如errormessageerror=15000代码>,但我不知道这是否正确,也不知道它是否会一直工作(想象一下,如果LoginMessage
中的所有字段都是可选的,它会工作吗?。不,这不会出错。枚举在序列化时只是整数,意外值存储在扩展数据中-因此字段1在消息之间完全可以互换。由于“user”是可选的,所以它是否存在并不重要——如果它存在但不是预期的,它将存储在扩展数据中
它似乎使用结构类型进行优化,因此不传输字段名或消息类型
这是正确的仅传输字段编号和数据。没有名字
区分消息的最好方法是通过某种前缀。最简单的方法是使用包装器消息:
message SomeWrapper {
optional LoginMessage login = 1;
optional ErrorMessage error = 2;
}
然后反序列化时,只需检查哪个字段有值。显然,在序列化时,也需要将值包装在SomeWrapper中。请注意,未包含的可选值产生的成本为零