前言

由于最近项目涉及到数据的传输和序列化,用的是XML,听专家说有ProtoBuff这个东西,于是周末实践了下,写出来做个记录。


ProtoBuff快速入门

what is ProtoBuff?


ProtoBuff即Protocol Buffers 是google公司弄出来的一个开源的用于传输数据协议格式的东西。一个作用类似于XML,JSON的东西,而且PB是google搞的,相信它的效率/性能应该不错。在接下来的具体实践中,我们将会直接感受它的一些其他特点,比如代码自动生成机制。


How to use PB?


so easy!


在windows环境下,准备好protobuf-java-2.5.0.jar及protoc.exe。


接下来,我们应该编写消息的数据格式了,比如SkuMessage.proto:


ProtoBuff实践_第1张图片


然后,就是代码自动生成了,如下:


ProtoBuff实践_第2张图片


分析:


  • PB应该是一个跨语言的


我们在命令行下,用java_out指示生成JAVA代码;其实还支持cpp_out,python_out


  • PB自动生成的代码的机制


根据我们提供的proto文件,自动为我们生成与这个消息对应的JAVA对象,同时我们不用在编写解析协议的代码了。更为重要的是,一旦协议发生变化,假设老协议是P1,新协议是P2,发送协议方S,接受协议消息的是R,其实我们只需要做的是在proto文件中变化下,然后是重新代码生成,在S中重新设置消息属性,在R中变化下而已;而且发送/接受方可以用不同语言编写,而2方的消息协议是一致的。


  • 向前兼容 AND 向后兼容 ?


【向前兼容】

如果我们的协议需要增加一行属性,发送方S升级了,但是接受方R没有变。


此时R能否识别新的协议呢?如果可以识别,那么新增的属性在R中应该是被忽略的。



【向后兼容】

如果我们的协议增加了一行属性,发送方S没有变化,但是接受方R升级了。


显然,S没有变化,R必然能识别老版本的协议。那么我们可以让这个属性是可选的,或者是有默认值的,这样就能影响R了。



模拟接受和发送消息


最后,我们看看下面的模拟发送和接受的代码:


ProtoBuff实践_第3张图片


说明:


第一,消息格式的文件名就是JAVA文件的文件名,因此我们提供的描述消息格式的proto文件名称应该符合JAVA类命名规范。


第二,proto文件名称应该与message名称不同,可以从代码角度发现  proto文件名.message名称就是我们需要发送的对象类型。


第三,对象的序列化,反序列化,这些都不必我们操心了,仅仅只需要writeTo,parseFrom即可,确实方便至极。


到这里,相信大家已经对PB了解几分了~



PB消息协议数据定义规则

我们是在proto文件中定义消息的,那么有哪些规则呢?


message 消息结构类型名{

  限定修饰符 数据类型 字段名 = 字段编码值 [字段默认值];

}


可以使用的限定修饰符如下:


required     必须的属性,发送方必须SET这个字段,否则在build这个消息对象时就报错!

optional      可选的属性,发送方可以不用SET这个字段,接受方GET这个字段不会报错!

repeated    这个属性可以设置多个值,相当于集合,实质上映射到JAVA代码上就是List!



PB数据类型  VS java数据类型


只需要注意些特殊的,就可以了,其他用常识吧~


int32 -> int

int64 -> long

......



一个复杂点的例子

PersonMsg.proto文件:


ProtoBuff实践_第4张图片


实例代码:


ProtoBuff实践_第5张图片