protocol buffer 知识整理(备份)
定义消息:
最简单的例子:
1 // 下面是a.proto文件的内容
2 syntax = "proto3"; //必须指明proto3,否则会被认为是proto2
3
4 message SearchRequest { /*这里是消息名*/
5 string query = 1; // 类型 字段名 = 标号; 注意:1-15是高效标号,19000-19999为协议保留
6 int32 page_number = 2;
7 int32 result_per_page = 3;
8 }
字段修饰符: singular 或repeated ,singular是默认修饰符,可以省略。
保留标识符:
为了避免升级导致的标号重用、字段重用、json序列化等问题,可以使用reserved来保留标号和字段名
1 message Foo {
2 reserved 2, 15, 9 to 11; //保留标号
3 reserved "foo", "bar"; //保留字段名
4 }
标量数值类型:
一个标量消息字段可以含有一个如下的类型——该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:
| .proto Type | Notes | C++ Type | Java Type | Python Type[2] | Go Type | Ruby Type | C# Type | PHP Type |
|---|---|---|---|---|---|---|---|---|
| double | double | double | float | float64 | Float | double | float | |
| float | float | float | float | float32 | Float | float | float | |
| int32 | 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint32替代 | int32 | int | int | int32 | Fixnum 或者 Bignum(根据需要) | int | integer |
| uint32 | 使用变长编码 | uint32 | int | int/long | uint32 | Fixnum 或者 Bignum(根据需要) | uint | integer |
| uint64 | 使用变长编码 | uint64 | long | int/long | uint64 | Bignum | ulong | integer/string |
| sint32 | 使用变长编码,这些编码在负值时比int32高效的多 | int32 | int | int | int32 | Fixnum 或者 Bignum(根据需要) | int | integer |
| sint64 | 使用变长编码,有符号的整型值。编码时比通常的int64高效。 | int64 | long | int/long | int64 | Bignum | long | integer/string |
| fixed32 | 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。 | uint32 | int | int | uint32 | Fixnum 或者 Bignum(根据需要) | uint | integer |
| fixed64 | 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 | uint64 | long | int/long | uint64 | Bignum | ulong | integer/string |
| sfixed32 | 总是4个字节 | int32 | int | int | int32 | Fixnum 或者 Bignum(根据需要) | int | integer |
| sfixed64 | 总是8个字节 | int64 | long | int/long | int64 | Bignum | long | integer/string |
| bool | bool | boolean | bool | bool | TrueClass/FalseClass | bool | boolean | |
| string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 | string | String | str/unicode | string | String (UTF-8) | string | string |
| bytes | 可能包含任意顺序的字节数据。 | string | ByteString | str | []byte | String (ASCII-8BIT) | ByteString | string |
默认值: 与go相似,是对应类型的“零值”
枚举的例子:
1 message SearchRequest {
2 string query = 1;
3 int32 page_number = 2;
4 int32 result_per_page = 3;
5 enum Corpus {
6 UNIVERSAL = 0;
7 WEB = 1;
8 IMAGES = 2;
9 LOCAL = 3;
10 NEWS = 4;
11 PRODUCTS = 5;
12 VIDEO = 6;
13 }
14 Corpus corpus = 4; //Corpus枚举类型,字段名是corpus, 标号为4(不是枚举中的值,是标号)
15 }
1 //是否允许枚举的值重复
2 enum EnumAllowingAlias {
3 option allow_alias = true; //开启这个选项才能允许重复
4 UNKNOWN = 0;
5 STARTED = 1;
6 RUNNING = 1; //与上面的STARTED重复
7 }
8
9 enum EnumNotAllowingAlias {
10 UNKNOWN = 0;
11 STARTED = 1;
12 // RUNNING = 1; // Uncommenting this line will cause a compile error inside Google and a warning message outside.
13 }
因为enum值是使用可变编码方式的,对负数不够高效,因此不推荐在enum中使用负数。
在消息中使用其他消息作为类型:
1 message SearchResponse {
2 repeated Result results = 1; //使用了下面的Result作为类型
3 }
4
5 message Result {
6 string url = 1;
7 string title = 2;
8 repeated string snippets = 3;
9 }
在消息A内定义消息B,并且在消息A内重复使用消息B。或者在外部消息C中重用消息B的定义:
1 message SearchResponse {
2 message Result { //在消息SearchResponse定义消息Result
3 string url = 1;
4 string title = 2;
5 repeated string snippets = 3;
6 }
7 repeated Result results = 1; //在消息SearchResponse内重用上面的Result定义作为类型
8 }
9
10 //外部重用
11 message SomeOtherMessage {
12 SearchResponse.Result result = 1; //需要指明父级
13 }
导入(重用其他.proto文件的定义):
import "myproject/other_protos.proto"; // 另外还有一种import public的东西,看图说话:
// new.proto
// All definitions are moved here // old.proto
// This is the proto that all clients are importing.
import public "new.proto"; //伪文件,导入old.proto的时候,会导入new.proto,依赖也会传递下去。用途类似unix的符号链接
import "other.proto"; // client.proto
import "old.proto";
// You use definitions from old.proto and new.proto, *** but not other.proto ***
升级建议:
- 不要更改任何已有的字段的数值标识。
- 如果你增加新的字段,使用旧格式的字段仍然可以被你新产生的代码所解析。你应该记住这些元素的默认值这样你的新代码就可以以适当的方式和旧代码产生的数据交互。相似的,通过新代码产生的消息也可以被旧代码解析:只不过新的字段会被忽视掉。注意,未被识别的字段会在反序列化的过程中丢弃掉,所以如果消息再被传递给新的代码,新的字段依然是不可用的(这和proto2中的行为是不同的,在proto2中未定义的域依然会随着消息被序列化)
- 非required的字段可以移除——只要它们的标识号在新的消息类型中不再使用(更好的做法可能是重命名那个字段,例如在字段前添加“OBSOLETE_”前缀,那样的话,使用的.proto文件的用户将来就不会无意中重新使用了那些不该使用的标识号)。
- int32, uint32, int64, uint64,和bool是全部兼容的,这意味着可以将这些类型中的一个转换为另外一个,而不会破坏向前、 向后的兼容性。如果解析出来的数字与对应的类型不相符,那么结果就像在C++中对它进行了强制类型转换一样(例如,如果把一个64位数字当作int32来 读取,那么它就会被截断为32位的数字)。
- sint32和sint64是互相兼容的,但是它们与其他整数类型不兼容。
- string和bytes是兼容的——只要bytes是有效的UTF-8编码。
- 嵌套消息与bytes是兼容的——只要bytes包含该消息的一个编码过的版本。
- fixed32与sfixed32是兼容的,fixed64与sfixed64是兼容的。
- 枚举类型与int32,uint32,int64和uint64相兼容(注意如果值不相兼容则会被截断),然而在客户端反序列化之后他们可能会有不同的处理方式,例如,未识别的proto3枚举类型会被保留在消息中,但是他的表示方式会依照语言而定。int类型的字段总会保留他们的
any/oneof 类型参考官方文档:
map:
语法:
map < key_type ,value_type > map_field = N ; //任何整数或字符串类型(因此,除了浮点类型之外的任何标量类型bytes)map的值不可以是repeated的。
map<string, Project> projects = 3; //Project是消息,map的key是string类型
包:
当然可以为.proto文件新增一个可选的package声明符,用来防止不同的消息类型有命名冲突。如:
package foo.bar;
message Open { ... } //在另一个包中:
message Foo {
...
required foo.bar.Open open = 1;
...
}
包标志对生成代码的影响依赖所选的语言(其他语言请参考官方文档): 在Go中, 包被作为Go package使用, 除非你在.proto文件中显式提供go_package选项.
定义服务:
例子:
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse); //入参是搜索请求,返回搜索响应
}
json选项:
1- 发送默认值(默认情况下,默认值是不发送的)
2- 忽略位置字段
3- 使用proto字段名,而非驼峰
4- 枚举字段用整数来发送,而非字符串
选项:
选项的作用访问来分:文件级别(文件顶部写)、消息级别、字段级别等。
optimize_for(文件选项):可以设置为SPEED,CODE_SIZE或LITE_RUNTIME
编译:
protoc --proto_path = IMPORT_PATH --java_out = DST_DIR--go_out = DST_DIRpath / to / file .proto //--proto_path可以多次指定,来解决多个导入路径的问题。
风格:
消息: 消息名使用驼峰法:SongServerRequest字段名使用下划线分隔:song_name.
枚举:枚举类型名使用驼峰法(首字母大写), 值的名字使用大写加下划线分隔:
enum Foo {
FIRST_VALUE = 1;
SECOND_VALUE = 2;
}
服务: 如果.proto文件定义RPC服务, 服务名和任何rpc方法应该用驼峰法(首字母大写):
service FooService {
rpc GetSomething(FooRequest) returns (FooResponse);
}
参考来源: protobuf官方文档 和 https://blog.csdn.net/feeltouch/article/details/80302860
protocol buffer 知识整理(备份)的更多相关文章
- ORACLE FLASHBACK DATABASE 知识整理
1.知识储备 1) 只有SYSDBA有权执行,闪回前一定要记录当前SCN 2) 需要停机,并要求处于ARCHIVELOG模式中 3) 闪回日志不能被复用和归档,是自动管理的.RVWR ...
- Golang 使用Protocol Buffer 案例
目录 1. 前言 2. Protobuf 简介 2.1 Protobuf 优点 2.2 Protobuf 缺点 2.3 Protobuf Golang 安装使用 3. Protobuf 通讯案例 3. ...
- [原创翻译]Protocol Buffer Basics: C#
Protocol Buffer 基础知识:c# 原文地址:https://developers.google.com/protocol-buffers/docs/csharptutorial ...
- Google Protocol Buffer 简单介绍
以下内容主要整理自官方文档. 为什么使用 Protocol Buffers .proto文件 Protocol Buffers 语法 编译.proto文件 Protocol Buffers API 枚 ...
- Kali Linux渗透基础知识整理(二)漏洞扫描
Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...
- wifi基础知识整理
转自 :http://blog.chinaunix.net/uid-9525959-id-3326047.html WIFI基本知识整理 这里对wifi的802.11协议中比较常见的知识做一个基本的总 ...
- Ggoogle Protocol Buffer的使用 (基于C++语言)
首先说明的是Protocol Buffle是灵活高效的.它的一个很好的优点(很重要的,我认为)就是后向兼容性--当我们扩展了了.proto文件后,我们照样可以用它来读取之前生成的文件. 之前已经写了关 ...
- Google Protocol Buffer的安装与.proto文件的定义
什么是protocol Buffer呢? Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准. 我理解的就是:它是一种轻便高效的结构 ...
- Protocol Buffer技术详解(数据编码)
Protocol Buffer技术详解(数据编码) 之前已经发了三篇有关Protocol Buffer的技术博客,其中第一篇介绍了Protocol Buffer的语言规范,而后两篇则分别基于C++和J ...
- ORACLE DATABASE 10G FALSHBACK 知识整理
1.知识储备 1) 当出现介质损坏时(如数据文件丢失),任何闪回方法都毫无用处,只能执行标准的备份.还原与恢复. 2.SCN记录方法 SQL>variable x_scn number; ...
随机推荐
- 你不知道的Linux shell操作
Linux Shell 脚本入门教程 Linux Shell 脚本是一种强大的工具,它允许您自动化日常任务和复杂操作.在本教程中,我们将逐步介绍几个实用的 Shell 脚本示例.每个示例都将详细说明, ...
- vue3关于.sync的用法
场景描述 我们都知道,子组件是不能够去修改父组件传递过来的数据. 因为如果子组件去修改父组件件传递过来的数据. 会导致数据的应用流向变得难以理解. 但是有些时候,我们需要当子组件的数据变化后,父组件的 ...
- forEach在项目中的使用
forEach 会改变原始数组 被forEach循环的数组不能够为空 forEach会改变原始数组 value是内容 index是索引 array是你写的数组. foeEach内部是异步的哈 功能描述 ...
- C# 中判断List集合是否为空
判断List集合是否为空,可以使用Count和Any,下面是其使用场景(别人总结)
- 多智能体强化学习算法【一】【MAPPO、MADDPG、QMIX】
相关文章: 常见多智能体强化学习仿真环境介绍[一]{推荐收藏,真的牛} 多智能体强化学习算法[一][MAPPO.MADDPG.QMIX] 多智能体强化学习算法[二][MADDPG.QMIX.MAPPO ...
- 【7】vscode不同的窗口样式和颜色插件peacock、设置打开多个窗口、md文件打开方式和预览以及插入目录
相关文章: [1]VScode中文界面方法-------超简单教程 [2]VScode搭建python和tensorflow环境 [3]VSCode 主题设置推荐,自定义配色方案,修改注释高亮颜色 [ ...
- Volatility 内存数字取证方法
计算机数字取证分为内存取证和磁盘取证,活取证与死取证,不管是那种取证方式,都应尽量避免破环犯罪现场,例如通过内存转储工具对内存进行快照,通过磁盘克隆工具对磁盘进行克隆,方便后期的分析工作,这里将研究内 ...
- Python 实现SynFlood洪水攻击
Syn-Flood攻击属于TCP攻击,Flood类攻击中最常见,危害最大的是Syn-Flood攻击,也是历史最悠久的攻击之一,该攻击属于半开放攻击,攻击实现原理就是通过发送大量半连接状态的数据包,从而 ...
- Advanced Installer傻瓜式打包教程
工具 Advanced Installer 11.0 前言 这个包不复杂,没有服务和注册表等操作,但需要.NET Framework 4.5和MySQL,同时需要初始化一下数据库,下面一起来实操一下. ...
- C#使用Tamir.SharpSsh.jsch上传文件异常Algorithm negotiation fail
环境 服务器:centos6.5 客户端:Windows 前言 项目中有一个exe,安装在客户端,其中有一个功能是将本地产生的文件上传至服务器,这个功能是以服务的方式安装在客户端上.之前一切好使,文件 ...