美文网首页
protocol buffers指南------定义消息类型

protocol buffers指南------定义消息类型

作者: Sirius_lwq | 来源:发表于2021-06-21 21:18 被阅读0次

    定义消息类型

    话不多说首先我们来看一个非常简单的例子。
    定义一个查询请求消息格式, 每个查询请求有一个查询语句,为了减少一次查询量,我们经常做分页查询,查询结果的第几页/每页结果数量。如下:

    syntax = "proto3";
    
    message SearchRequest {
      string query = 1;
      int32 page_number = 2;
      int32 result_per_page = 3;
    }
    
    
    1. 第一行指明当前使用的是proto3语法, 如果不指定则默认为proto2。必须是.proto文件的除空行和注释内容之外的第一行
    2. SearchRequest 消息定义指明了3个字段。每个字段有名字和类型.

    字段类型

    上面例子中, 所有字段都是Scalar Types/标量(通俗说基础)类型(后面会详细讲述), 包括两个int32和一个string. 此外还可以支持复合类型包括枚举类型.

    指定标签

    可以看到消息定义的每个字段都有一个唯一的数字型标签. 这个标签用于在消息的二进制格式中标识字段, 一旦消息类型被使用后不可以再修改.

    标签的值在1和15之间时编码只需一个字节,包括标识值和字段类型。标签在16到2047之间将占用两个字节。因此应该将从1到15的标签分派给最频繁出现的消息元素。记得保留一些空间给以后可能添加的频繁出现的元素.

    可以指定的最小的标签值是1, 最大的是2的29次方-1, 即536870911。 另外19000到19999(FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber)不能使用, 是Protocol Buffers的实现自己保留这个标签段.

    指定字段规则

    消息字段可以是下列之一:

    1. singular: 一个定义良好的消息可以有0个或1个此字段(但是不能超过1个),该规则是V3版本默认规则
    2. repeated: 这个字段可以在定义好的消息中重复任意次(包括0次),重复值的顺序和原顺序一致(类似于数组)。

    V3版本中,基础类型定义额repeated会默认进行packed编码以提高效率。例如:

     repeated int32 samples = 4 [packed=true];
    
    

    添加更多消息类型

    可以在单个 .proto 文件中定义多个消息类型. 推荐定义多个相关消息, 例如, 如果你想定义应答消息格式来相应你的SearchResponse消息类型,建议放到同一个.proto文件.

    message SearchRequest {
      string query = 1;
      int32 page_number = 2;
      int32 result_per_page = 3;
    }
    
    message SearchResponse {
     ...
    }
    
    

    添加注释

    可以使用C/C++风格的"//"语法在.proto文件中添加注释;或者"/****/"

    /* SearchRequest represents a search query, with pagination options to
     * indicate which results to include in the response. */
    
    message SearchRequest {
      string query = 1;
      int32 page_number = 2;  // Which page number do we want?
      int32 result_per_page = 3;  // Number of results to return per page.
    }
    
    

    保留字段

    当你更新pb文件版本时,需要删除一个字段时, 或者注释掉它, 后续的新的接口版本重用这个标签的数字,而已有的老版本程序仍然使用.proto文件的老版本,就会出现bug。 为了确保防止该bug产生, 我们可以指明这个要删除的字段为保留字段.。如果未来任何用户试图复用这个字段标识protocol buffer的编译器就会告警。

    message Foo {
      reserved 2, 15, 9 to 11;
      reserved "foo", "bar";
    }
    
    

    注意: 不能在同一个保留字段声明中混合使用名字和标签数字

    .proto可以生成什么?

    对.proto文件执行protocol buffer的编译时, 编辑器会生成你所选语言的代码,用来处理你在文件中定义的消息类型, 包括读写字段值, 序列化消息到输出流, 和从输入流中解析消息.

    • 对于c++, 编译器为每个.proto文件生成.h和.cc文件, 并为每个在文件中描述的消息类型生成一个类
    • 对于Java, 编译器为每个消息类型生成一个.java文件, 还有用于创建消息实例的Builder类.
    • Python小有不同 - Python编译器为.proto文件中的每个消息类型生成带有静态描述符的模块, 这些模块将和metaclass一起在运行时用来创建必须的Python数据访问类.
    • 编译器生成一个.pb.go文件, .proto文件中的每个消息类型在这个文件中都有一个类型.
    • 对于Ruby, 编译器生成一个.rb文件, 带用包含消息类型的Ruby模块.
    • 对于JavaNano, 编译器输出类似java但是没有builder类.
    • 对于Objective-C, 编译器从每个.proto文件生成一个pbobjc.h和pbobjc.m文件,文件中描述的每个消息类型都有一个类.
    • 对于C#, 编译器从每个.proto文件生成一个.cs文件,文件中描述的每个消息类型都有一个类.
    • 对于Go语言,编译器针对一个.proto文件生成一个pb.go文件,为每个message生成一个类型

    相关文章

      网友评论

          本文标题:protocol buffers指南------定义消息类型

          本文链接:https://www.haomeiwen.com/subject/kkfhyltx.html