6

我有一个定义如下的原型模式,

message User {
   int64 id = 1;
   bool email_subscribed = 2;
   bool sms_subscribed = 3;
}

现在根据官方proto3 文档,默认值不会序列化以在有线传输期间节省空间。但在我的情况下,我想接收客户端是否明确设置true/false了字段email_subscribed/sms_subscribed(因为这些值是true以前的,但现在用户想要取消订阅)。因此,当客户端发送false这些字段中的任何一个时,生成器代码序列化器只会忽略这些字段。

我如何实现这一点并避免在上述情况下省略这些字段?

PS:我使用 Javascript 作为我的 GRPC 客户端和 Python 和 GRPC 服务器。

4

2 回答 2

6

更新:最近通过optional关键字的新含义重新引入了存在跟踪信息 proto3,这种情况发生了变化:

message User {
   optional int64 id = 1;
   optional bool email_subscribed = 2;
   optional bool sms_subscribed = 3;
}

通过此更改(现在在 protoc 等中可用),即使它是隐式默认值,也会传输显式分配。


你不能在proto3下。您最好的选择可能是定义一个未指定的三布尔枚举作为第一个值为零的项目,然后是一些真/假值。

这将需要与protobuf相同的空间bool,但不兼容二进制 - 因此您不能简单地更改现有消息上声明的成员类型。好吧,我想如果您设置为 true === 1,那么至少它仍然有效 - 对于过渡,您必须预料到 false / not specified 是模棱两可的,直到您刷新任何旧数据。

另一种选择是为 each 添加一个bool fooSpecified成员bool foo,但这会占用更多空间并且由于是手动的而容易出错。

于 2018-05-02T08:20:39.083 回答
2

另一种选择是将包装器与 proto3 一起使用。它们基本上将您的值包装在一条消息中,因此在父消息中它可以保留为空。

这样,您可以通过一些额外的工作来区分布尔字段上的 null / false / true。

于 2020-01-04T12:52:12.513 回答