proto使用

一.参考:

文档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())。

你可能感兴趣的:(proto使用)