zoukankan      html  css  js  c++  java
  • protocol buffer开发指南

    ProtoBuf 是一套接口描述语言(IDL)和相关工具集(主要是 protoc,基于 C++ 实现),类似 Apache 的 Thrift)。用户写好 .proto 描述文件,之后使用 protoc 可以很容易编译成众多计算机语言(C++、Java、Python、C#、Golang 等)的接口代码。(摘自:ProtoBuf 与 gRPC 你需要知道的知识

    注:本文参考Protocol Buffers 3.0 技术手册,下面给出该文章中未说明的部分

    定义Message类型

    1 syntax = "proto3";
    2 
    3 message SearchRequest {
    4   string query = 1;
    5   int32 page_number = 2;
    6   int32 result_per_page = 3;
    7 }

     

      首行指定了使用proto3语法,如果没有改行,protocol buffer编译器默认使用proto2。

      field numbers

      4,5,6行中指定了field number,field number的取值范围为1~(229-1)。protocol buffer的预留了19000~19999(FieldDescriptor::kFirstReservedNumber ~ FieldDescriptor::kLastReservedNumber)之间的值。

      field rules

    消息字段有2种规则:

    • singular:0或1个,但不能多于1个
    • repeated:任意数目 

      default

      当解析 message 时,如果被编码的 message 里没有包含特定变量,根据类型不同,他们会有不同的默认值:

    • string:默认是空的字符串
    • byte:默认是空的bytes
    • bool:默认为false
    • numeric:默认为0
    • enums:定义在第一位的枚举值,也就是0
    • messages:根据生成的不同语言有不同的表现,参考generated code guide

    注意:对于scalar(标准protobuf类型,如) message字段,一但message被解析,则没有办法来明确判断该字段设置了默认值(如没法判断一个boolean变量设置为false)或根本没有设置。因此在定义message类型的时候一定要注意,例如,如果不想在默认下有任何动作,则boolean的值在false时不要有动作。此外注意,scalar message字段在设置为默认值时,该值不会被序列化--->即反序列化scalar message字段时是无法反序列化出默认值(因为默认值不会被序列化)

    • 不要修改任何已存在的变量的 Tag
    • 如果你新增了变量,新生成的代码依然能解析旧的数据,但新增的变量将会变成默认值。相应的,新代码序列化的数据也能被旧的代码解析,但旧代码会自动忽略新增的变量。
    • 废弃不用的变量使用两个OBSOLETE_"前缀或用 reserved 标注
    • int32、 uint32、 int64、 uint64 和 bool 是相互兼容的,这意味你可以更改这些变量的类型而不会影响兼容性
    • sint32 和 sint64 是兼容的,但跟其他类型不兼容
    • string 和 bytes 可以兼容,前提是他们都是UTF-8编码的数据
    • fixed32 和 sfixed32 是兼容的, fixed64 和 sfixed64是兼容的
    • enum和int32,int64,uint32,uint64是兼容的(注意:如果类型不一致可能会被截断)。需要注意的是,客户端解码message时可能会给出不同的解释,如未识别的proto3 enum类型会保存在message中,但如何解释则依赖于解码的语言。
    • 改变一个新加的oneof成员值是安全且二进制兼容的;为现有的oneof添加字段则不安全。

    未识别的字段

      未识别的字段为序列数据中出现的无法解析的字段,如当老的二进制解析器解析一个包含新字段的二进制时,新字段即为无法识别的字段。

      proto3可以很好地解析未识别的字段,然而proto实现时可能会也可能不会保留这些未知的字段,功能实现不应该依赖于未知字段是否保留或丢弃。

    oneof

      oneof类似C语言的联合体union,oneof中不能使用repeated

    option

      所有有效的选项都定义在google/protobuf/descriptor.proto,参见option

    使用场景 

    多消息流

      如果向一个文件或流中写入多个消息,则需要自己去跟踪一个消息的结束和下一个消息的开始。由于protocol buffers不会对自限定长度,解析器无法判定消息的结束点,简单的方式是在写入消息前先写入消息的长度。

    大数据集

      protocol buffer并不是设计用来处理大消息的,如果有大规格的消息,可以分割解决。

    参考:Language Guide (proto3)

     

  • 相关阅读:
    [Docker]一键部署gitlab中文版
    [Docker]python 2.7.5 docker-compose安装
    [CentOS7]pip安装
    快速傅里叶变换FFT
    HDU 4734 f(x)
    DP
    HDU 3555 Bomb
    HDU 5898 odd-even number
    将文本拷贝到剪贴板
    数论分块
  • 原文地址:https://www.cnblogs.com/charlieroro/p/9011900.html
Copyright © 2011-2022 走看看