protobuf 语法 与 protocol-buffers 的使用
前言
protocol-buffers 是 node.js 平台对支持 protobuf 封装的三方模块,下面的例子都通过 protocol-buffers 的使用来说明。
什么是protobuf
Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,与 XML 和 JSON 数据格式类似,但采用的是二进制的数据格式,具有更高的传输,打包和解包效率,它们用于 RPC 系统和持续数据存储系统。
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
如何使用protocol-buffers
1.编写.proto文件
该文件规定了数据的格式、类型等,语法在后面会写到
message Data { required string name = 1; required int32 id = 2; required bool sex = 3; required float money = 4; }
2.编码
const protobuf = require('protocol-buffers') const fs = require('fs') let schema = protobuf(fs.readFileSync(__dirname+'/data.proto','utf-8')) let buf = schema.Data.encode({ id:1, name:'Joe', sex: true, money: 58.8 }) console.log(buf)
引入下载好的protocol-buffers模块,schema为传入.proto文件后生成的Message对象,里面有对应的编解码方法。
schema.Data 的名称和.proto文件内写的message对象名称要一致
调用encode方法,传入的数据格式类型和.proto文件的保持一致,编码之后会得到一个buffer
<Buffer 0a 03 4a 6f 65 10 01 18 01 25 33 33 6b 42>
3.解码
schema.Data.decode(buf)
调用decode方法,传入buffer解码出对应的数据对象
.proto文件语法
字段规则
- required: 格式良好的 message 必须包含该字段一次
- optional: 格式良好的 message 可以包含该字段零次或一次(不超过一次)。
- repeated: 该字段可以在格式良好的消息中重复任意多次(包括零)。其中重复值的顺序会被保留。
字段定义组成
message Data { optional int32 id = 1[default = 10]; }
- optional: 字段规则
- int32: 字段类型
- id: 字段名称
- 1: 唯一标识符
- [default = 10]: 可选的选项
缺省值
在未接收到数据时会得到默认值
- int: 0
- string: 空字符
- bool: false
- enum: 枚举的第一项
枚举enum
枚举规定字段值在预定义的值列表中,值为大于等于0的整数
enum Fruits{ APPLE = 1; BANANA = 2; CHERRY = 3; } message Data { Fruits fruits = 1[defalut = BANANA]; }
对应js格式:
{ fruits: 1 } 或 { fruits: 2 } 或 { fruits: 3 }
嵌套的message
message Works { string work = 1; } message Data { string name = 1; int32 id = 2; Works works = 3; }
对应js格式:
{ name: 'Joe', id: 1, works: { work: 'worker' } }
repeated(基本类型)
message Data { repeated int32 nums = 1; }
对应js格式:
{ nums: [1,2,3,4,5] }
repeated(嵌套message)
message People { string name = 1; int32 height = 2; } message Data { repeated People people = 1; }
对应js格式:
{ people: [ { name: 'Mike', height: 180 }, { name: 'Joe', height: 190 } ] }