1. 简单介绍

protobuf文件:就是定义你要的消息(类似Java中的类)和消息中的各个字段及其数据类型(类似java类中的成员变量和他的数据类型)

2. Protobuf消息定义

消息由至少一个字段组合而成,类似于C语言中的结构。每个字段都有一定的格式。

字段格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]

1)限定修饰符包含 required\optional\repeated

Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。

Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。

Repeated:表示该字段可以包含[0,N]个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。

2)数据类型

Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型.

protobuf 数据类型

描述

打包

C++语言映射

bool

布尔类型

1字节

bool

double

64位浮点数

N

double

float

32为浮点数

N

float

int32

32位整数、

N

int

uin32

无符号32位整数

N

unsigned int

int64

64位整数

N

__int64

uint64

64为无符号整

N

unsigned __int64

sint32

32位整数,处理负数效率更高

N

int32

sing64

64位整数 处理负数效率更高

N

__int64

fixed32

32位无符号整数

4

unsigned int32

fixed64

64位无符号整数

8

unsigned __int64

sfixed32

32位整数、能以更高的效率处理负数

4

unsigned int32

sfixed64

64为整数

8

unsigned __int64

string

只能处理 ASCII字符

N

std::string

bytes

用于处理多字节的语言字符、如中文

N

std::string

enum

可以包含一个用户自定义的枚举类型uint32

N(uint32)

enum

message

可以包含一个用户自定义的消息类型

N

object of class

N 表示打包的字节并不是固定。而是根据数据的大小或者长度。

例如int32,如果数值比较小,在0~127时,使用一个字节打包。

关于枚举的打包方式和uint32相同。

关于message,类似于c语言中的结构包含另外一个结构作为数据成员一样。

关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.

3)字段名称

字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。

protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.

4)字段编码值

有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。

编码值的取值范围为 1~2^32(4294967296)。

其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16.

1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。

protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。

消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。

建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。

5)默认值。

当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。

3. 注意

1)关于import

protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。

2)关于package

避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。

3)关于message

支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。

关于enum

枚举的定义和C++相同,但是有一些限制。

枚举值必须大于等于0的整数。

使用分号(;)分隔枚举变量而不是C++语言中的逗号(,)

eg.

enum VoipProtocol

{

H323 = 1;

SIP  = 2;

MGCP = 3;

H248 = 4;

}

 
 

google protobuf 中的proto文件编写规则的更多相关文章

  1. Google protobuf proto文件编写规则

    转载自: http://blog.csdn.net/yi_ya/article/details/40404231 1. 简单介绍 protobuf文件:就是定义你要的消息(类似java中的类)和消息中 ...

  2. 在Google Maps中导出KML文件

    教你一招:在Google Maps中导出KML文件 2011-07-11 15:24:49 4819 人阅读 作者:上方文Q 编辑:上方文Q [复制链接] [爆料] Google Earth的一大乐趣 ...

  3. Python3.6安装protobuf模块+将proto文件转换成pb2.py文件

    Python对版本的对应即为苛刻,笔者第一次安装时遇到了很多坑,比如无法将proto文件转换成py文件,转换了之后文件无法使用,网上各种各样的解决办法都没有讲到重点.其实会出现各种各样的问题是由于版本 ...

  4. Caffe源码中caffe.proto文件分析

    Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下caffe.proto文件. 在src/caffe/proto目录下有一个 ...

  5. .gitignore文件编写规则

    1.gitignore说明 在使用git的过程中,一般我们总会有些文件无需纳入git的管理,也不希望它们总出现在未跟踪文件列表,这些文件通常是日志文件.临时文件.编译产生的中间文件.工具自动生成的文件 ...

  6. 【OpenWRT】【RT5350】【三】MakeFile文件编写规则和OpenWRT驱动开发步骤

    一.Makefile文件编写 http://www.cnblogs.com/majiangjiang/articles/3218002.html 可以看下上面的博客,总结的比较全了,在此不再复述 二. ...

  7. C# 读取指定文件夹中的全部文件,并按规则生成SQL语句!

    本实例的目的在于: 1 了解怎样遍历指定文件夹中的全部文件 2 控制台怎样输入和输出数据 代码: using System; using System.IO; namespace ToSql{ cla ...

  8. 大陆用户如何下载Google Play中的apk文件

    利用一些中转网站完成,具体原理可能是以手机虚拟机形式下载,然后提取app,给出下载链接,不过知不知道原理不重要,反正都是被墙. 这里给出测试可用的网站apkpure(20160714) http:// ...

  9. 《Dotnet9》系列-Google ProtoBuf在C#中的简单应用

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

随机推荐

  1. P1725 琪露诺

    P1725 琪露诺 单调队列优化dp 对于不是常数转移的dp转移,我们都可以考虑单调队列转移 然而我们要把数组开大 #include<cstdio> #include<algorit ...

  2. apache单ip配置多端口多站点

    1.修改 /etc/httpd/conf/httpd.conf 添加一个Listen,如: Listen 80 Listen 8001 Listen 8002 2.添加一个VirtualHost #v ...

  3. django生命周期示意图

    1.图示

  4. 1.Mysql集群------Docker下的Mysql主从复制

    前言: 实话说,我想做的是Mysql集群架构. 我的计划是: 1.实现Docker下的Mysql主从复制 2.实现MyCat基于Mysql的读写分离 3.实现MyCat的分库分表 4.实现pxc集群 ...

  5. Github学生包的申请

    Github Education为了大学生们更好的进行开发,进行边做边学,与一些合作伙伴和朋友一起创建GitHub学生开发者包. 里面内容非常丰富,应有尽有: AWS 亚马逊云服务 $75-$150  ...

  6. java通过FreeMarker模板生成Excel文件之.ftl模板制作

    关于怎么通过freemarker模板生成excel的文章很多,关键点在于怎么制作模板文件.ftl 网上的办法是: (1)把Excel模板的格式调好,另存为xml文件 (2)新建一个.ftl文件,把xm ...

  7. C#基础-委托与事件

    委托 delegate是申明委托的关键字 返回类型都是相同的,并且参数类型个数都相同 委托声明 delegate double DelOperater(double num1, double num2 ...

  8. cacti和nagios监控web平台搭建

    在linux的运维中对服务器的监控,时刻了解服务器的状态是确保服务能够正常允许的条件,linux的服务监控平台有很多, cacti 下面对cacti(仙人掌),一种比较流行的开源监控软件做安装配置 具 ...

  9. 使用windows api安装windows服务程序(C#)

    3个步骤: 1.安装器代码编写 2.安装器工具类编写 1)安装.启动服务) 2)卸载服务 3.windows服务程序编写(参考:多线程.方便扩展的Windows服务程序框架) 4.代码下载,在文末(注 ...

  10. Python函数及参数

    ## 函数 - 函数是代码的一种组织形式,一般一个函数完成一个特定功能 - 函数需要先定义后使用 - 函数的定义 def func_name(参数): func_body ... return fun ...