protobuf&Javascrip编码解码演示
start
- 写一下
protobuf
相关知识 - 记录在
python
环境和js
环境中如何处理protobuf
。
1. protobuf是什么?
1.1 介绍
Protocol Buffers
(简称Protobuf
) ,是Google
出品的序列化框架,与开发语言无关,和平台无关,具有良好的可扩展性。Protobuf
和所有的序列化框架一样,都可以用于数据存储、通讯协议。
Protobuf
支持生成代码的语言包括Java、Python、C++、Go、JavaNano、Ruby、C#,官网地址是https://developers.google.com/protocol-buffers/。
Portobuf
的序列化的结果体积要比XML、JSON小很多,XML和JSON的描述信息太多了,导致消息要大;此外Portobuf
还使用了Varint
编码,减少数据对空间的占用。
Portobuf
序列化和反序列化速度比XML、JSON快很多,是直接把对象和字节数组做转换,而XML和JSON还需要构建成XML或者JSON对象结构。
大白话来解释就是 Portobuf 是类似 JSON 一样的数据传输格式化的格式,它的特点就是字节数组,也就是
Buffers
1.2 使用
新建一个文件 lazy_tomato.proto
// 文件名: lazy_tomato.proto
syntax="proto3"; //定义语法版本,我这里使用的是 proto3
// 定义一个对象,然后定义它包含的属性,以及属性的类型,以及属性的索引
message Person {
int32 age = 1;
string name = 2;
}
这个文件需要插件处理,转换成我们对应语言的文件去使用。
python语言就需要把`lazy_tomato.proto`这个文件转换成 .py
js语言就需要把`lazy_tomato.proto`这个文件转换成 .js
ps:可以提前转换好;也可以直接读取文件然后实时处理,我这里演示就用提前转换好的效果演示)
1.2.1 python转换
python转换的话,下载工具:https://github.com/google/protobuf/releases
下载后解压,bin目录下有protoc.exe
软件。
可以加环境变量也可以不加,直接打开命令行窗口,然后记录一下我们的软件存放的文件目录,直接拿来调用。
# D:\lazy_tomato\protoc.exe就是我们的程序路径,直接去调用
# --version 查看版本
D:\lazy_tomato\protoc.exe --version
# --python_out 转换成python版本
# ./ 同级目录
# lazy_tomato.proto 文件名
D:\lazy_tomato\protoc.exe --python_out=./ lazy_tomato.proto
1.2.2 js转换
之前 python
下载的软件,我看旧版本 3.20.x
的还是支持 js
的,目前的最新文档就没看到支持 js
了。
我尝试的使用旧版本3.20.x
版本的也可以转换,但是在使用时不知道如何使用,也没啥文档。
百度到的也有很多其他第三方库转换,但是也都缺少文档,最终寻找很久,还是采用 npm
中最热门的库:[protobufjs](https://www.npmjs.com/package/protobufjs)
。
看了下这个库,在维护,周下载次数2千万左右,有官方文档,很合理。
文档说到,可以直接使用工具,即可处理静态资源,当然他也提供动态处理的方法。
# 官网推荐安转到项目中,我感觉我这个工具全局都想用,可以考虑直接安装到全局
npm install protobufjs-cli --save-dev
使用 pbjs 转换 .proto 文件
在命令行中,你可以使用 pbjs
命令将 .proto
文件转换为 JavaScript 文件。例如,要将 lazy_tomato.proto
转换为静态模块(commonjs 格式),可以使用以下命令:
pbjs -t static-module -w commonjs -o lazy_tomato.js lazy_tomato.proto
这里的参数解释如下:
-t static-module
:指定输出类型为静态模块。-w commonjs
:指定包装格式为 CommonJS(适用于 Node.js)。如果你需要用于浏览器,可以使用-w es6
或其他适当的格式。-o lazy_tomato.js
:指定输出文件名。lazy_tomato.proto
:输入的.proto
文件。
使用生成的 JavaScript 文件
一旦你生成了 JavaScript 文件,你就可以在你的 Node.js 项目中使用它。
编码解码示例
const protobuf = require("protobufjs");
const $root = require('./lazy_tomato.js')
const Person = $root.Person
const message = Person.create({
name: "John Doe",
age: 14,
});
const buffer = Person.encode(message).finish();
console.log('buffer', buffer);
const decodedMessage = Person.decode(buffer);
console.log('decodedMessage', decodedMessage);
buffer <Buffer 08 0e 12 08 4a 6f 68 6e 20 44 6f 65>
decodedMessage Person { age: 14, name: 'John Doe' }