参考链接:https://github.com/protobufjs/protobuf.js#installation
简介
Protocol Buffers是一种跨语言、跨平台、可扩展的序列化结构化数据的方式,用于通信协议、数据存储等,最初由Google设计。
protobuf.js是一个纯JavaScript实现,支持node.js和浏览器的TypeScript。它易于使用,速度惊人,并且可以与.proto文件一起开箱即用!
目录
1、标题安装(如何在项目中使用protobuf.js。)
npm install protobufjs
或者
开发环境:
<script src=“//cdn.jsdelivr.net/npm/protobufjs@7.X.X/dist/protobuf.js“></script>
生产环境:
<script src=“//cdn.jsdelivr.net/npm/protobufjs@7.X.X/dist/protobuf.min.js“></script>
用项目所依赖的确切版本替换版本标记。
文件转换
.proto文件
option java_package = "test";
option java_outer_classname = "TestProtocol";
message Address{
required string province = 1;
required string city = 2;
optional string country = 3;
}
安装pbjs
npm -g install protobufjs-cli
使用pbjs命令将.proto文件转换为.json文件
pbjs -t json src/lib/proto/chat.proto > src/lib/proto/chat.proto.json
生成js静态模块文件
pbjs -t static-module -w commonjs -o src/lib/proto/chat.js src/lib/proto/chat.proto
生成ts声明文件
pbts -o src/lib/proto/chat.d.ts src/lib/proto/chat.js
该库支持CommonJS和AMD加载程序,还可以作为protobuf导出到全局。
库的类型 | 地址 |
---|---|
Full | https://cdn.jsdelivr.net/npm/protobufjs/dist/ |
Light | https://cdn.jsdelivr.net/npm/protobufjs/dist/light/ |
Minimal | https://cdn.jsdelivr.net/npm/protobufjs/dist/minimal/ |
2、用法(使用工具集的简单介绍)
由于JavaScript是一种动态类型语言,protobuf.js引入了有效消息的概念,以提供最佳性能
有效消息
一个有效的消息是一个对象:
- 不缺少任何必需的字段
- 仅由编辑器能转化的JS类型组成
有两种可能的有效消息类型,为了方便,编码器可以同时使用这两种类型:
- Message instances :消息实例
- Plain JavaScript objects:纯JavaScript对象
简而言之,wire编写器(代码生成器)能够解析类型
文件类型 | 预期js类型(create, encode) | 转换(fromObject) |
---|---|---|
s-/u-/int32 or s-/fixed32 | number(32位整数) | value 或者0(如果有符号)如果无符号,则value >>>0 |
s-/u-/int64 or s-/fixed64 | Long(最佳)number(53位整数) | Long.fromValue(value) 否则 parseInt(value,10) |
float or double | number | Number(value) |
bool | boolean | Boolean(value) |
string | string | String(value) |
bytes | Uint8Array or Buffer or Array. | 如果是字符串base64.decode(value)/长度非零的对象为类似缓冲区 |
enum | number(32位整数) | 如果是字符串,则查找数字id |
message | 有效消息 | Message.fromObject(value) |
- 如果字段是可选的,则显式undefined和null被视为未设置
- 重复字段为Array.
- Map字段是Object<string,T>,其中键是相应值的字符串表示形式,或8个字符长的二进制哈希字符串。
- 标记为最佳的类型提供最佳性能,因为不需要转换步骤(即数字到低位和高位或base64字符串到缓冲区)
工具集
出于性能原因,每个消息类都提供了一组不同的方法,每个方法只做一件事。这避免了不必要的断言/冗余操作,其中性能是一个问题,但也迫使用户在必要时显式执行验证。
注意,下面提及到的消息指的是任何消息类。
- Message.verify(message: Object): null|string
验证一个纯JavaScript对象是否满足有效消息的要求,从而可以毫无问题地进行编码。如果有问题的话,verify不抛出错误而会将错误消息作为字符串返回。
var payload = "invalid (not an object)";
var err = AwesomeMessage.verify(payload);
if (err)
throw Error(err);
- Message.encode(message: Message|Object [, writer: Writer]): Writer
编码消息实例或有效的纯JavaScript对象。此方法不会隐式验证消息,由用户确定有效负载是有效消息。
var buffer = AwesomeMessage.encode(message).finish();
- Message.encodeDelimited(message: Message|Object [, writer: Writer]): Writer
工作方式与Message.encode类似,但附加地将消息长度作为变量 - Message.decode(reader: Reader|Uint8Array): Message
将protobuffer解码为消息实例。如果缺少必需的字段,它将抛出util.ProtocolError,并将实例属性设置为到目前为止已解码的消息。如果wrie格式无效,则会抛出错误
try {
var decodedMessage = AwesomeMessage.decode(buffer);
} catch (e) {
if (e instanceof protobuf.util.ProtocolError) {
// e.instance保存到目前为止已解码的消息,其中缺少必填字段
} else {
// wire 格式是无效的
}
}
-
Message.decodeDelimited(reader: Reader|Uint8Array): Message
工作方式与Message.decode类似,但会另外读取一个消息的长度作为变量的预设值。 -
Message.create(properties: Object): Message
创建一个满足有效消息要求的新消息实例。建议使用Message.create而不是Message.fromObject,因为它不执行可能的冗余转换
var message = AwesomeMessage.create({
awesomeField: "AwesomeString" });
- Message.fromObject(object: Object): Message
将任何无效的纯JavaScript对象转换为消息实例
var message = AwesomeMessage.fromObject({
awesomeField: 42 });
// 将awesomeField转换为字符串
- Message.toObject(message: Message [, options: ConversionOptions]): Object
将消息实例转换为任意的纯JavaScript对象,以便与其他库或存储互操作。生成的纯JavaScript对象可能仍然满足有效消息的要求,这取决于指定的实际转换选项,但大多数情况下都不满足
var object = AwesomeMessage.toObject(message, {
enums: String, // enums作为字符串名称
longs: String, // longs作为字符串(需要long.js)
bytes: String, // 字节作为base64编码字符串
defaults: true, // 包含默认值
arrays: true, // 即使默认值为false,也填充空数组(重复字段)
objects: true, // 即使默认值为false,也填充空对象
oneofs: true // 包含设置为当前字段名称的虚拟字段之一
});
作为参考,下图旨在显示不同方法与有效消息概念之间的关系:
verify表示直接在纯对象上调用create或encode[分别生成有效消息]。另一方面,fromObject从更广泛的普通对象进行转换,以创建有效的消息。
3、入门示例
使用.proto文件
可以使用完整的库加载现有的.proto文件,该库将解析和编译定义,以备使用(基于反射)消息类:
// awesome.proto
package awesomepackage;
syntax = "proto3";
message AwesomeMessage {
string awesome_field = 1