protobufjs 使用
安装
- npm i protobufjs
- npm i protobufjs-cli
这是 pbjs/pbts 的命令行工具,旧版的 protobufjs pbjs/pbts 是直接在包内的,最新的分开了
导入
- 默认:
import protobufjs from "protobufjs";
- 指定版本:
import protobufjs from "protobufjs/minimal.js";
pbjs/pbts 生成
pbjs
使用 es6 的生成类型
npx pbjs -t static-module -w es6 -l eslint-disable --es6 --keep-case -o ./test.js ./*.proto
后处理
-
-------------------------------分割-----------------------------
import * as $protobuf from "protobufjs/minimal";
替换为
import $protobuf from "protobufjs/minimal.js";
-
-------------------------------分割-----------------------------
const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
替换为
const $root = {};
pbts
由于 creator 模块规范限制导入 js 必须存在扩展名(.js),所以我们导出的文件名后缀必须是 *.js.d.ts
npx pbts -m -o ./声明文件名.js.d.ts ./proto静态模块.js
怎么添加消息号?
目前论坛里的方法都是通过 二次包装 或者 拼接消息号 实现
- 二次包装:消息号的消息体包装消息 bytes 类型的消息体
proto 定义
message send_data { uint32 id = 1; bytes body = 2; } message send_data_body { string data = 1; }
使用
/** 消息体字节 */ const body = test.send_data_body.encode(test.send_data_body.create({ data: "1" })).finish(); /** 消息 */ const mess = test.send_data .encode( test.send_data.create({ id: 100, body: body, }) ) .finish();
- 拼接消息号:将消息号添加到消息数据头部
使用
const buff = new ArrayBuffer(消息号占用字节 + 消息体占用字节); const data2 = new Uint8Array(buff); const data3 = new DataView(buff); // 设置消息号 data3.setUint16(0, 消息号); // 设置消息体 data2.set(消息体, 2);
有没有更高效更方便的方式呢?当然是有的,我在自己的框架中实现了这种方式,也就是使用 默认值
proto 定义
message test { uint32 __id = 1 [default = 100]; string data = 2; }
使用
const body = test.test.create({ data: "1" }); body["__id"] = body["__id"]; const mess = test.test.encode(body).finish();
使用默认值的好处
- 发送消息不需要传递消息号
- 更好的性能
性能比较
-
1w 次
-
10w 次
proto 定义
package test; >syntax = "proto3"; message test { uint32 __id = 1 [default = 100]; string data = 2; } message send_data { uint32 id = 1; bytes body = 2; } message send_data_body { string data = 1; }
标签:body,cocos,const,creator,教程,send,消息,test,data From: https://www.cnblogs.com/muzzik/p/17060955.html测试代码
// 二次包装 { this._log.time_start("二次包装"); let temp: any; for (let k_n = 0; k_n < for_n; ++k_n) { /** 消息体字节 */ const body = test.send_data_body.encode(test.send_data_body.create({ data: "1" })).finish(); /** 消息 */ temp = test.send_data .encode( test.send_data.create({ id: 100, body: body, }) )> .finish(); } this._log.time_end("二次包装"); } // 拼接消息号 { this._log.time_start("拼接消息号"); for (let k_n = 0; k_n < for_n; ++k_n) { /** 消息体字节 */ const body = test.send_data_body.encode(test.send_data_body.create({ data: "1" })).finish(); const buff = new ArrayBuffer(2 + body.length); const mess = new Uint8Array(buff); const data_view = new DataView(buff); // 设置消息号 data_view.setUint16(0, 100); // 设置消息体 mess.set(body, 2); } this._log.time_end("拼接消息号"); } // 默认消息号(mk 框架) { this._log.time_start("默认消息号"); let temp: any; for (let k_n = 0; k_n < for_n; ++k_n) { const body = test.test.create({ data: "1" }); // eslint-disable-next-line no-self-assign body["__id"] = body["__id"]; temp = test.test.encode(body).finish(); } this._log.time_end("默认消息号"); }