网上大部分小程序使用protobuf的都是微信小游戏的解决方案,弄了半天终于整理出微信小程序使用Protobuf的可行方案。找的方案不是动态解析,而是根据.proto文件生成json文件再手动生成js文件,过程比较复杂。
1. github 项目 https://github.com/Zhang19910325/protoBufferForWechat 这个项目是关键,将其weichatPb放进小程序目录下。
2、安装pbjs工具
首先安装好环境,我是Mac 直接 brew install npm
安装好执行以下命令
npm install -g protobufjs
安装成功再执行 pbjs
接着对.proto文件进行处理
我是user.proto
///////////////
syntax = "proto3";
message User{
string UserID = 1; // 用户ID
string Token = 2; // 用户Token
}
/////////////
进入对应文件夹 使用命令
pbjs -t json user.proto > user.json
这样就生成了 user.json文件
{
"nested": {
"User": {
"fields": {
"UserID": {
"type": "string",
"id": 1
},
"Token": {
"type": "string",
"id": 2
}
}
}
}
}
再对其进行改造,创建一个user.js文件
module.exports = {
"nested": {
"User": {
"fields": {
"UserID": {
"type": "string",
"id": 1
},
"Token": {
"type": "string",
"id": 2
}
}
}
}
}
最后使用该文件
以下是我微信小程序的代码
var protobuf = require('../../weichatPb/protobuf.js');
var awesomeConfig = require('./proto.js');//加载awesome.proto对应的json
var AwesomeRoot = protobuf.Root.fromJSON(awesomeConfig);
var AwesomeMessage = AwesomeRoot.lookupType("User");
var User = { UserID: "123", Token:"666" };
var message = AwesomeMessage.create(User);
var buffer = AwesomeMessage.encode(message).finish();
// buffer为protobuf数据
服务端使用Go语言搭建一个websocket服务器,可以解析出小程序发送过来的protobuf数据,但是直接转发过来就出问题,因为websocket发送过来的为string数据,小程序解析失败。后来改成服务端发送base64代码,小程序调用wx.base64ToArrayBuffer函数则可以。
以下为服务端代码:
func DealMSG(data string, websocket *network.Websocket) {
fmt.Println([]byte(data))
User := user.User{}
err := proto.Unmarshal([]byte(data), &User)
fmt.Println(err)
fmt.Println(User.GetToken(), User.GetUserID())
User.Token = "999"
User.UserID = "888"
data1, err := proto.Marshal(&User)
fmt.Println(err)
encodeString := base64.StdEncoding.EncodeToString(data1)
}
func main() {
Server := network.NewWebSocketServer("127.0.0.1:80", "/im", 1000)
Server.SetDealMsgFun(DealMSG)
Server.Listen()
}
小程序接收数据代码:
wx.onSocketMessage(
function (res){
var data = wx.base64ToArrayBuffer(base64encode(res.data));
console.log(data,buffer)
var deMessage1 = AwesomeMessage.decode(buffer);
var deMessage = AwesomeMessage.decode(data);
console.log("deMessage", deMessage.Token,deMessage.UserID);
}
)
发现此方法太麻烦,不希望base64转换一遍,最终找到一个函数可以使 string转换为ArrayBuffer
最后服务端直接发送protobuf数据,小程序代码如下
wx.onSocketMessage(
function (res){
var data = char2buf(res.data )
var deMessage = AwesomeMessage.decode(data);
console.log("deMessage", deMessage.Token,deMessage.UserID);
}
)
function char2buf(str) {
var out = new ArrayBuffer(str.length)
var u8a = new Uint8Array(out)
var strs = str.split("")
for (var i = 0; i < strs.length; i++) {
u8a[i] = strs[i].charCodeAt()
}
return out
}
最终解决小程序使用protobuf问题。
小程序发送 User 数据至服务端 , 服务端修改其数据再发送回来。
目前只是简单使用还没遇见坑。