protobuf 语法 与 protocol-buffers 的使用

时间:2022-07-23
本文章向大家介绍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
    }
  ]
}