如何在不影响原有属性的前提下对序列化的proto消息进行字段扩充?
问题解答
首先纠正你给出的proto示例的笔误:同一个消息内的字段编号必须唯一,你示例中name和id都用了字段号2是非法定义,我们默认修正为string name = 1; int32 id = 2;的合理版本进行解答。
答案是可以实现,核心依赖Protobuf本身的未知字段保留机制,具体情况如下:
- 如果你使用的是proto3 v3.5及以上版本、或是任意版本的proto2:不需要修改任何业务代码即可实现需求。B用旧版(无id字段)的M定义解析A发来的消息时,识别不到的id字段会被作为未知字段自动存储在消息实例中,你只要直接在解析得到的实例上修改
name字段值后序列化转发,未知的id字段会被一起序列化,C用新版M解析就能同时拿到id和B补充的name内容。 - 如果你使用的是proto3 v3.0~v3.4版本:这个区间的proto3默认会丢弃未知字段,两种解决方式可选:
- 升级B服务依赖的Protobuf库版本到3.5及以上,无需修改业务代码
- 无法升级的话,在B使用的M的proto定义中添加全局配置
option preserve_unknown_fields = true;,开启未知字段保留开关即可
- 注意规避一个错误用法:如果B的逻辑是收到A的消息后,手动新建一个空的M实例,把解析得到的
name等已知字段逐个拷贝到新实例再修改转发,这种操作不会把未知的id字段复制到新实例,会导致id丢失。只要改成直接在解析得到的原始消息实例上修改name字段即可。
内容的提问来源于stack exchange,提问作者Asaf Ben Aharon
相关产品推荐
相关产品推荐

