Protocol Buffers 学习(1):定义一个消息

栏目: 服务器 · 发布时间: 7年前

内容简介:Protocol Buffers 学习(1):定义一个消息

首先让我们来看一个非常简单的例子。 假设你想定义一个消息格式,用来表示搜索请求,其中每个搜索请求都有三项:

  • 一个查询字符串
  • 你感兴趣的特定结果页
  • 以及每个页面的结果数

下边是用来定义消息类型的 .proto 文件

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}
  • 第一行表示使用的protocol版本是3,如果你不写这一条, protobuf 会认为你使用的是 protobuf2 ,而且,这行必须是第一行,前边也不能有注释
  • SearchRequest 这条消息定义了三个字段(名称/值对),每条消息都要包含这三个字段,每个字段都有一个名称和一个类型

字段类型说明

在上面的例子中,所有字段都是基本类型:两个整数(page_number和result_per_page)和一个字符串(query)。这些字段也可以是复合类型,包括枚举和其他消息类型

字段标签

消息定义中的每个字段都有唯一的编号标签,这些标记用于以消息二进制格式标识字段,消息开始使用之后就 不能修改

注意:

  • 值在1到15范围内的标签需要一个字节进行编码,包括标识号和字段类型
  • 在16到2047范围内的标签占用两个字节。

因此,你应该为非常频繁出现的消息元素保留标签1到15。记住要为可能在将来添加的频繁出现的元素留出一些空间。

最小的标签是1,最大的标签是 536870911 ,即 2^29 - 1 ,并且 19000 - 19999protobuf 系统保留标签,不能使用这几个

字段规则说明

一共有两种类型

  • singular: 一个符合规则的消息应该具备零个或者一个该字段
  • repeated: 一个符合规则的消息可以有零个或者任意个该字段,并且保留重复的顺序,在 proto3 中,基本类型的重复字段默认压缩编码

添加更多消息类型

可以在单个 .proto 文件中添加多个消息类型,例如

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

message SearchResponse {
 ...
}

添加注释

可以使用 //.proto 文件添加注释。例如

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.
}

保留字段(字段修改或者删除解决办法)

当消息类型更新或者删除时,这些被修改的字段的标签如果继续使用,会造成数据不正确的问题,这时需要把这些标签保留起来,防止跟旧版本的数据发生冲突。

(当使用JSON序列化时, 字段名称 也有可能存在这个问题),通俗来说,就相当于已经上线了使用A接口的一个APP,这个时候服务端如果想修改A接口的数据格式,只能新增一个接口,并且肯定不能使用A接口的地址

案例

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

这就表示 2,15,9,10,11,"foo", "bar"都不能重复使用了

.proto 文件会生成什么?

当编译 .proto 文件时,编译器将根据你选择的语言生成对应代码,你需要使用文件中描述的消息类型,包括获取和设置字段值,将消息序列化 输出流,以及解析来自输入流的消息

  • 对于PHP,编译器会为每个消息生成一个类,用来描述该消息
  • 对于C ++,编译器从每个 .proto 生成 .h.cc 文件,并为您的文件中描述的每个消息类型指定一个类
  • 对于Java,编译器会为每个消息类型生成一个带有类的 .java 文件,以及用于创建消息类实例的特殊Builder类
  • Python有点不同, Python编译器生成一个模块,其中包含 .proto 中每个消息类型的静态描述符,然后使用元类在运行时创建必要的 Python 数据访问类
  • 对于Go,编译器会为文件中的每种消息类型生成一个具有类型的.pb.go文件
  • 对于Ruby,编译器生成一个包含消息类型的包含 Ruby 模块的.rb文件
  • 对于JavaNano,编译器输出与 Java 类似,但没有Builder类
  • 对于Objective-C,编译器从每个 .proto 生成一个 pbobjc.hpbobjc.m 文件,在文件中描述的每个消息类型都有一个类
  • 对于C#,编译器从每个 .proto 生成一个 .cs 文件,在文件中描述的每个消息类型都有一个类

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Linux设备驱动程序

Linux设备驱动程序

科波特 / 魏永明、耿岳、钟书毅 / 中国电力出版社 / 2006-1-1 / 69.00元

本书是经典著作《Linux设备驱动程序》的第三版。如果您希望在Linux操作系统上支持计算机外部设备,或者在Linux上运行新的硬件,或者只是希望一般性地了解Linux内核的编程,就一定要阅读本书。本书描述了如何针对各种设备编写驱动程序,而在过去,这些内容仅仅以口头形式交流,或者零星出现在神秘的代码注释中。 本书的作者均是Linux社区的领导者。Jonathan Corbet虽不是专职的内核......一起来看看 《Linux设备驱动程序》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换