其实上一篇文章只是介绍了pblua的生成~具体与真实服务器通讯还是有一段距离的~~比如怎么生成cmd key 怎么序列化,反序列化结构体,怎么广播到处理逻辑等等
1 > proto key 的制作与例子(用来标记是什么proto的玩意)
由于lua不支持enum,所以我们会使用table来描述proto key,到时候用于网络的通讯。我们的结构如下,基本上都差不多是这个样子的了
ProtoKey={测试代码
VerifyVer_C="1", //客户端 请求 key
VerifyVer_S="2", //服务器 下发 key
}
function PrintCmdKey(value)
for k,v in pairs(ProtoKey) do
if(v==value) then
print(">>>>处理消息key = "..k..' ,value = '..v);
end
end
end
PrintCmdKey("2");
2 > 序列化文件并发送给服务器(生成proto_pb文件看第二篇文章)
local login = LoginCommand_pb.PlayerVerifyVerLoginClientCmd(); //这里是proto的结构
login.game=3;
login.zone=9;
login.version='1.3.3'; //赋值
local msg = login:SerializeToString();
----------------------------------------- -----------------------
local buffer = ByteBuffer.New();
buffer:WriteBuffer(msg);
NetManager:SendMessage(ProtoKey.VerifyVer_C, buffer);
首先 注册需要用 什么来处理这条消息服务器的返回
Event.AddListener(ProtoKey.VerifyVer_S, this.PbLuaCallback);
然后处理反序列化
function PromptCtrl.PbLuaCallback(buffer)
print("lua PromptCtrl.PbLuaCallback");
local data = buffer:ReadBuffer();
local msg = LoginCommand_pb.PlayerVerifyVerLoginClientCmd();
msg:ParseFromString(data);
print('PbLuaCallback: msg.zone:>'..msg.zone..'msg.game:>'..msg.game..'msg.version:>'..msg.version);
end
====================================================================================================================================
遇到的问题
1> ByteBuffer 是作者的一种buffer的封装格式,如果要使用protobuf 那么你必须修改里面的写长度的,和读长度的地方,否则服务器的protobuf没法解析
public void WriteString(string v) {
byte[] bytes = Encoding.UTF8.GetBytes(v);
// writer.Write((ushort)bytes.Length);
bufferLength = bytes.Length;
writer.Write(bytes);
}
public void WriteBytes(byte[] v) {
// writer.Write((int)v.Length);
bufferLength = v.Length;
writer.Write(v);
}
public string ReadString() {
// ushort len = ReadShort();
byte[] buffer = new byte[bufferLength];
buffer = reader.ReadBytes(bufferLength);
return Encoding.UTF8.GetString(buffer);
}
public byte[] ReadBytes() {
//int len = ReadInt();
return reader.ReadBytes(bufferLength);
}
2 > 包的结构顺序必须满足自己的
作者的是
buffer:WriteShort(Login);
buffer:WriteByte(ProtocalType.PBC);
buffer:WriteBuffer(code);
仔细查看作者socket代码会发现底层是写了一个proto的长度的,如果你在lua层想满足 如下的包结构就没办法了。
proto长度(ushort)+protokey+proto 内容
所以我们的修改了NetManager 使得可以发送一个protokey 我们的结构
NetManager:SendMessage(ProtoKey.VerifyVer_C, buffer); 最后代码如下
<pre name="code" class="html"> /// <summary> /// 写数据 /// </summary> void WriteMessage(ushort cmdkey, byte[] message) { MemoryStream ms = null; using (ms = new MemoryStream()) { ms.Position = 0; BinaryWriter writer = new BinaryWriter(ms); ushort msglen = (ushort)message.Length; writer.Write (msglen); ushort s = cmdkey; writer.Write(s); writer.Write(message); writer.Flush(); if (client != null && client.Connected) { byte[] payload = ms.ToArray(); Util.PrintBytes (">>>>>WriteMessage", payload); outStream.BeginWrite(payload, 0, payload.Length, new AsyncCallback(OnWrite), null); } else { Debug.LogError("client.connected----->>false"); } } }
==========================================================收包流程==================================================================
跟大部分网络游戏没啥区别,这里只是加入了 PureMVC的处理而已