代码之家  ›  专栏  ›  技术社区  ›  Christopher Pisz

grpc和protobuf——当另一方不同步释放时,如何处理新字段

  •  0
  • Christopher Pisz  · 技术社区  · 3 年前

    我遇到的情况是,grpc通信的另一端与他们的发布不同步。因此,我的上级希望我在短时间内(比如两周)添加一个字段,如果对方填写或不填写,该字段将起作用

    我相信我可以通过将其添加到proto消息的末尾来实现这一点,这样其他字段的索引就不会改变。根据我在谷歌上搜索到的,可选字段在3.15版本之前不可用,所以我必须使用变通方法。

    向我描述的解决方法是使用 oneof .然而,我不是100%确定那是什么样子。所有的例子都显示了场本身。属于其中一个值的索引是否独立于属于消息其余部分的索引?

    message TestMessage {  
        string somefield = 1;
        int someotherfield = 2;
        oneof mynewoptionalfield
        {
            string mynewfield = ???? Does this have to be 3 or is it 1?
            int ifihadanother = ???? Does this need to be 4 or 2?
        } 
    }
    

    问题:

    • 我使用的指数是什么???马克是
    • 当另一方不打算重新编译并部署对原型文件的更改时,这是正确的解决方法吗?
    • 我如何检查字段是否用C++代码填充?
    0 回复  |  直到 3 年前
        1
  •  6
  •   Eric Anderson    3 年前

    你的用例正是protobufs设计用来处理的。你需要做的就是:在消息中添加一个新字段。在最简单的情况下,客户机应用程序代码在服务器推出完成之前不会查看新字段,因此不会注意到它有时存在,有时缺失。

    您不应该更改已有字段的索引(字段ID),这是正确的。尽管我会注意到你可以添加你的新字段 在任何地方 在信息中;字段的写入顺序对protobuf并不重要。

    因此,您只需添加另一个字段,如:

    message TestMessage {  
        string somefield = 1;
        int someotherfield = 2;
        string mynewfield = 3;
    }
    

    你没有 使用 3 作为id,你可以使用4、10或10000。但是对于protobuf来说,小数字更有效,通常只选择“下一个”id。在连线上,protobuf使用id来标识字段,所以以后不要更改id很重要。

    在protobuf 3中,所有字段在protobuf 2的意义上都是“可选的”;没有“必填”字段。然而,protobuf 2也为所有油田提供了“现场存在”。Protobuf 3仅为其中一个OF和消息提供现场存在。。。直到最近重新引入“可选”关键字。

    在protobuf 3中如果你打电话 textMessage.getMynewfield() 会的 总是 返回一个非空字符串。如果未发送字符串,它将使用空字符串( "" ).对于整数 0 返回,对于消息,返回“默认消息”(所有默认值)。这对于许多用例来说已经足够了,可能对您来说已经足够了。

    但假设你需要区分 "" <notsent> .这就是现场存在所提供的。 信息 在protobuf 3中,有返回的“has”方法 true 如果存在一个值。但是原语没有这种存在信息。一个选项是使用 standard wrappers 使原语成为信息。protobuf较新版本中的另一个可用选项是 optional 关键词。这两个选项都将提供一种类似 textMessage.hasMynewfield() .

    message TestMessage {  
        string somefield = 1;
        int someotherfield = 2;
        google.protobuf.StringValue mynewfield = 3;
        // -or-
        optional string mynewfield = 3;
    }