protobuf 的介绍这里就不在讲述。本文介绍使用的是 decodeio不是google-protobuf。使用的版本是v6.10.2
mac环境
完成该功能参考了一下文章:
- https://blog.csdn.net/u010799737/article/details/104025745
- https://www.jianshu.com/p/746bb9d81380
- https://blog.csdn.net/weixin_33985507/article/details/91415907
一、安装 decodeio
- github地址: https://github.com/protobufjs/protobuf.js
- 安装方式:
sudo npm install protobufjs
- 配置环境:“/xxxx/protobufjs/bin”:$PATH
- protobufjs 安装完成后,输入:
pbjs
命令,等待其安装完相关组件为止
二、生成 proto 文件对应的 js
我的项目中有多个 proto 文件,其中大厅有 request.proto和response.proto 游戏中也有这两个文件。由于微信小游戏不支持加载的 function 所以本文只用转换成 js 的形式。
- request.proto : 发送数据格式
- response.proto: 接收数据格式
request.proto 内容:
// protoc --go_out=. *.proto
syntax = "proto2";
package protobuf;
// 请求命令
message HallRequestCmd {
required HallReqHead head = 1;
}
// 内容
message HallReqHead {
required int32 uid = 1;
required int32 msgID = 2;
required string app = 3;
optional string hallMsg = 4;
}
response.proto 内容:
// protoc --go_out=. *.proto
syntax = "proto2";
package protobuf;
// 响应命令
message HallResponseCmd {
required HallRespHead head = 1;
}
// 响应头定义
message HallRespHead {
required int32 uid = 1;
required int32 msgID = 2;
required string app = 3;
optional string hallMsg = 4;
}
游戏的这两个文件内容就不在贴出来了,因为内容太多
生成 js 命令
-
生成单个 proto 的 js:
pbjs -t static-module -w commonjs -o request_pb.js request.proto
-
将目录中的所有 proto 生成一个 js:
pbjs -t static-module -w commonjs -o proto.js *.proto
我的项目中是把一对 request 和 response 生成一个 js,要注意多个 proto 生成一个 js 时 proto 文件中的消息名不要相同。如果生成多个 js,要注意 proto 文件中的 package 不能相同,不然使用的时候找不到对应的消息
-
将上面生成的 proto.js 文件拖到项目中
三、使用
let proto = require("../protobuf/proto");
let head = proto.protobuf.HallRequestCmd.create({head: {uid: 123, msgID: 1122, app: "app_123"}}); // 创建消息
let buffer = proto.protobuf.HallRequestCmd.encode(head).finish(); // 编译
let msg = proto.protobuf.HallResponseCmd.decode(buffer); // 解码
console.log("buffer: " + buffer);
console.log("msg: " + JSON.stringify(msg));
打印如下:
使用解码方法时需要注意 decode
的参数必须是Uint8Array
的数据,websocket 设置的数据格式是arraybuffer
类型1,所以需要做转换,代码如下:
let uint8Data = new Uint8Array(data);
message = build.decode(uint8Data);
WebSocket.binaryType = “arraybuffer”; // 使用二进制的数据类型 ↩︎