14

我有一个客户端-服务器应用程序,服务器将 protobuf 格式的序列化对象传输给客户端,我想停用一个required字段。不幸的是,我不能同时更改客户端和服务器以使用新.proto定义。

如果我将一个required字段更改为optional,但仅用于序列化消息的代码(即反序列化代码尚未重建并且仍然认为它是一个required字段),我可以继续发布可以反序列化的消息,只要我填充一个值现在optional-场?

(这样做似乎很好,至少对于我尝试过的一些微不足道的情况(仅使用Java),但我感兴趣的是它是否是一种普遍合理的方法,以及是否有任何边缘情况等我应该担心)。

动机:我的目标是停用required客户端-服务器应用程序中的一个字段,其中服务器发布由客户端反序列化的消息。我的预期方法是:

  1. required将字段更改为optional在主干上。
  2. 如果需要部署新的服务器代码(用于不相关的功能/修复),请确保在消息中继续填充可选字段
  3. 逐步为所有客户部署更新的代码(这需要时间,因为它需要其他团队参与他们自己的发布计划)
  4. 确认所有客户端都已更新。
  5. 开始停用(即不填充)可选字段。
4

2 回答 2

22

根据编码格式文档,是否需要字段并没有编码在序列化字节流本身中。也就是说,optional或者required对编码的序列化消息没有影响

我已经在实践中确认了这一点,使用 Java 生成的代码,通过将序列化消息写入磁盘并比较输出 - 使用包含所有支持的原始类型以及表示其他类型的字段的消息。

于 2012-12-03T00:42:03.720 回答
3

只要设置了该字段,使用parseFrom(byte[])反序列化的方法仍然可以工作,因为 byte[] 将是相同的。

但是,有人会想知道为什么在您准备好允许它成为可选字段之前,您要将字段从必需更改为可选?基本上,您只是在 .proto 文件中将其设为“可选”,但您通过始终填充它来强制要求它。只是一个想法。

于 2012-12-03T00:34:02.167 回答