zoukankan      html  css  js  c++  java
  • Protobuf 从入门到实战

    简介

          从第一次接触Protobuf到实际使用已经有半年多,刚开始可能被它的名字所唬住,其实就它是一种轻便高效的数据格式,平台无关、语言无关、可扩展,可用于通讯协议数据存储等领域。

     

    优点

    • 平台无关,语言无关,可扩展;
    • 提供了友好的动态库,使用简单;
    • 解析速度快,比对应的XML快约20-100倍;
    • 序列化数据非常简洁、紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10。

    使用详解

    1、服务器安装

    安装依赖的库:     autoconf automake libtool curl make g++ unzip

    安装:

      1 $ ./autogen.sh
      2 $ ./configure
      3 $ make
      4 $ make check
      5 $ sudo make install

    2、 安卓客户端安卓

                   下载相应版本jar包即可。(csdn上上传了nano版本的jar包和exe文件)

    3、 项目实战

           首先举一个服务端和客户端按照Protobuf协议进行数据数据传输的例子,工作流程如下图:(图下方深色部分为服务端部分,上方浅色部分为客户端部分)

    PB协议工作流程 (2)

    1、服务端和客户端约定他们使用PB协议作为数据传输和存储的工具,并约定传输信息的字段,如下:里面定义支付传输的字段。

      1 syntax = "proto2";          // PB协议版本
      2 import "Common.proto";      // 引入Common.proto,位于Protobuf sdk中
      3 
      4 option optimize_for = LITE_RUNTIME;
      5 
      6 option java_package = "com.xxxx.entity.pb";    // 生成类的包名
      7 option java_outer_classname = "PayInfo";       // 生成类的类名
      8 
      9 message PayInfo{
     10 	required string payid = 1;             // 支付相关的字段信息
     11 	optional string goodinfo = 2;          // optional 为可选参数
     12 	required string prepayid = 3;          // required为必填参数
     13 	optional string mode = 4;
     14 	optional int  userid = 5;
     15 	repeated string  extra = 6;           // repeated 为数组
     16 }

    2、通过Protobuf源码编译得到可运行程序(也可以在网上查找下载,注意PB协议的版本)。得到exe程序中,在windows环境下通过命令行窗口命令生成上述文件中定义的PayInfo.java文件。(protoc 为可执行的exe文件)

      1 protoc --java_out ./ ./PayInfo.proto

    3、将生成PayInfo文件集成到项目代码中,同时需要引入 ProtoBuf的sdk(因为生成的PayInfo.Java类中引入了sdk中的类),可以在github上下载:https://github.com/google/protobuf

    4、服务端通过支付信息初始化PayInfo类,并调用ProtoBufSDK中 com.google.protobuf.nano 类的 toByteArray()方法将PayInfo转化为字节数组,通过网络传输给客户端(可以进行加密和压缩操作,注意顺序)。

      1 public static final byte[] toByteArray(MessageNano msg) {
      2         byte[] result = new byte[msg.getSerializedSize()];
      3         toByteArray(msg, result, 0, result.length);
      4         return result;
      5     }

    5、客户端拿到字节数据后,通过集成的PayInfo.java文件对字节数据解析成PayInfo对象(通过程序生成的java文件都会自动生成这个函数)。

      1 public static PayInfo parseFrom(byte[] data)

    自此:客户端就顺利拿到了服务端发送的支付信息,可以通过他们调起支付宝或者微信客户端发起支付了。

    由此可以看出ProtoBuf只是一种协议,一种存储数据的格式,对应上面生成的字节数据的格式,任何语言的程序都可以通过本地类和jar包将字节数据解析成对象(语言/平台无关)

    使用建议:

    1、通过编译程序生成.java文件有不同的版本,建议使用nano版本(3.0之后的PB协议才发布该版本),这种版本生成的java文件方法数较少(没有set,get等函数),对APK的体积影响更小(四五个文件大前后相差80~90Kb,项目中后续作了替换)。命令:

      1 protoc_3.1.0.exe  --javanano_out ./ ./GetConfig.proto

    2、不管用2.0还是3.0还是nano版本还是非精简版最终生成的字节数据文件是相同的,不影响前后端的交互。

    与其它数据协议比较

         Protobuf 有如 XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。Protobuf 语义更清晰,无需类似 XML 解析器的东西(因为 Protobuf 编译器会将 .proto 文件编译生成对应的数据访问类以对 Protobuf 数据进行序列化、反序列化操作)。

         和其它数据协议的比较如下图:

    image

    为什么Protobuf作为数据传输协议如此高效?

    1. 数据小:

      a) 同json相比较,它不需要传递key值,而是用第几个元素成员变量来表示(而且index使用varient来存储,只占用一个字节)。

      b) 它还会开辟一个字节存放 该字符串的长度,用于直接查找字符串。

      c) 不需要传输','/‘:’等不必要的分隔符,存储没有浪费。

      其存储格式如下:

    2. 解析速度快:

    json解析成对象的话,需要将每个成员变量的key值到整个json串中匹配查找key。而在protobuf中直接通过比较tag序列就可以了,而且值的获取也可以直接通过legth获取,所以解析速度非常快。

    参考:

    https://developers.google.com/protocol-buffers/

    https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

    https://tech.meituan.com/serialization_vs_deserialization.html

  • 相关阅读:
    HarmonyOS Java UI之DirectionalLayout布局
    【HarmonyOS HiSpark IPC DIY Camera】hi3518wifi的配置与使用
    《鸿蒙开发板外设控制》直播答疑(初学者必看)
    【鸿蒙应用开发】确切位置布局PositionLayout
    鸿蒙应用开发之怎么更好的远程连接手表模拟器做调试
    [Hi3861]实现S1,S2,User三个物理按键的独立事件下(DTButtonV0.0.3)
    鸿蒙开发板外设控制 之 实现物理按键的“长按事件”(按键通用框架 V0.0.2)
    单一方向布局实现音乐播放UI
    鸿蒙系统应用开发之JS实现一个简单的List
    动态设置cxgrid列的Properties
  • 原文地址:https://www.cnblogs.com/NeilZhang/p/8410589.html
Copyright © 2011-2022 走看看