一.参考:
文档1,文档2,文档3
二、项目使用步奏 (环境:proto3 版本 websocket:Server;c++ ;Client: js )
1.首先需要创建一个 后缀为.pro 协议文件
syntax = "proto3";
package game_pb_msg;
message PB_gameEndInfo
{
uint32 gameNum = 1;
uint32 winCount = 2;//注释=》ok
//注释=》no !!!
}
注意:坑 (package 后面的 game_pb_msg 与文件名务必相同,微信ios小游戏加载配置会有问题,另外:注释 空格注意)
2.使用这个.pro文件生成目标语言代码,服务器是c++,工具网盘地址https://pan.baidu.com/s/1Pq8p0ZgHIIHtxrf2-k3tVA
3.Client:
下载nodejs,引入protobufjs库,加载.proto协议文件
var ProtoBuf = require("protobufjs");
a.监听服务器消息处理:
//服务器数据包括包头数据长度8 ,先解析包头数据
let msgHeader ={
identity :0,// 0x06: ProBuffer; 0x05: 自定义;//1个字节长度 0x06: ProBuffer; 0x05: 自定义;非6的数据不用处理
encode :0,//1个字节长度
length :8,//消息长度初始为包头长度8// 数据长度,协议头长度为8
version :0,//1个字节长度 //版本号信息//0x04: ProBuffer; 0x03: 自定义
reserve :0,//1个字节长度
cMsgType :0,//
};
for(let i=0;i<8;i++){
msgHeaderview.setUint8(i,msgView.getUint8(i));
}
msgHeader.identity=msgHeaderview.getUint8(0);
msgHeader.encode=msgHeaderview.getUint8(1);
msgHeader.length=msgHeaderview.getUint16(2);
msgHeader.version=msgHeaderview.getUint8(4);
msgHeader.reserve=msgHeaderview.getUint8(5);
msgHeader.cMsgType=msgHeaderview.getUint16(6);
//然后解析数据
var bodybuffer =new ArrayBuffer(recv_msg.byteLength -8);
var bodyview =new DataView(bodybuffer);
for (var _i =0;_i < pb_msg_array.byteLength -8;_i++) {
bodyview.setUint8(_i,msgView.getUint8(_i +8));
}
//最后业务流程可得到想要数据pbData:
this.PBDDZGame = require("loadProtoMgr").getProtoMgr().getPB("game_pb_msg");//加载.proto协议文件
let pbData =this.PBDDZGame.PB_PointDemandReq.decode(bodyview);//反序列
cc.log("结果",pbData.gameNum,pbData.winCount);
b.发送数据给Server
let leaveReq =new this.ddzNet.PBGAMEFrame.DPB_TablePlayerLeaveMsg();
leaveReq.iuserid =this.playerInfo.getSelfUserId();
leaveReq.cleavetype =5;
this.login_socket.send(pB_MsgType.PB_TABLE_PLAYER_LEAVE_MSG,readyMsg,this.serverType);//将序列好的数据发送
let pb =this.PBGAMEFrame.DPB_TablePlayerLeaveMsg.encode(readyMsg);//以下测试代码
cc.log("xxxxxbbbbb",pb)
let xx =this.PBGAMEFrame.DPB_TablePlayerLeaveMsg.decode(pb);
cc.log("xxxxvbnbbnnxxxbbbbb",xx,xx.toArrayBuffer().byteLength)
4.Server:
a.发送给Client
game_pb_msg::PB_DealCardsServer proBuf;
proBuf.set_ibasescore(res.iBaseScore);
if (!proBuf.SerializeToArray(m_serializeData + m_headerLen, proBuf.ByteSize()))//序列化发送给客户端
{
__log(_ERROR, __FUNCTION__, "SerializeToArray ERROR len:%d\n",len);
return NULL;
}
pServer->SendMsgToClient(.......)
game_pb_msg::PB_DealCardsServer proBuf2;//测试:从内存中读取并反序列化PB_DealCardsServer 对象
if (!proBuf2.ParseFromArray(m_serializeData + m_headerLen, proBuf.ByteSize()))
{
printf("xxc 2\n");
}
b.接受客户端消息处理
PB_PointDemandReq pbReq;
if (!pbReq.ParseFromArray(reqBuffer, len))//反序列化后得到数据
{
__log(_ERROR, __FUNCTION__, "ParseFromArray ERROR\n");
return NULL;
}
PointDemandReq req = { 0 };
req.cPointDemand = pbReq.cpointdemand();
不管是Server还是Client 发送数据是序列化(SerializeToArray() / encode() ),收到消息是反序列化(ParseFromArray() / decode())。