学堂 学堂 学堂公众号手机端

Unity手游网络通讯Protobuf的逻辑《接收消息》

lewis 4年前 (2021-11-01) 阅读数 7 #技术


欢迎加入Unity业内qq交流群:956187480


项目结束了就需要有个总结了。


1.消息事件接收

public void OnRecveHandler(object sender, RecvEvent e)
{
_dispatcher.AddData(e.Message, e.BytesTransferred);
}
public void AddData(byte[] data, int actualSize)
{
SocketData socketdata = new SocketData();
socketdata.data = data;
socketdata.actualSize = actualSize;
mQueue.Enqueue(socketdata);
}

2.实时监测消息队列

public void Update()
{
_dispatcher.IncomingData();
}

public void IncomingData()
{
while (this.mQueue.Count > 0)
{
SocketData socketdata = (SocketData)this.mQueue.Dequeue();
this.mIProcessData.IncomingData(socketdata.data, socketdata.actualSize);
}
}

3.处理消息队列的消息

//拿到服务器的消息后处理一下
public void IncomingData(byte[] data, int actualSize)
{
if (actualSize >= SocketClient.BUFFER_SIZE)
{
Debug.Log("当前大小 actualSize:" + actualSize);
throw new Exception("Buffer Overflow!");
}

actualSize = data[3] << 16 | data[2] << 8 | data[1];
List<byte> a = data.ToList();
buffer = new List<byte>();
buffer = a.GetRange(0,actualSize);
this.mCallback.SendMessage(buffer.ToArray<byte>());


//截取第一个消息后剩余的消息,如果剩余不为空说明黏包了,做递归处理
List<byte> b = a.GetRange(actualSize, a.Count - actualSize);
//消息的123位为消息长度
int bSize = b[3] << 16 | b[2] << 8 | b[1];
//判断是否黏包
if (bSize != 0)
{
IncomingData(b.ToArray<byte>(), b.Count);
}
}
-------------------------------------------------------------------------
public void SendMessage(byte[] data)
{
if (callback != null)
{
callback(data);
}
}
------------------------------------------------------------------------
callback.callback += GetServerMessage;

4.处理后的消息进行解析

private void GetServerMessage(byte[] data)
{
int MdmNum;
int CmdNum;
object obj = _packetParser.Parse(data, out MdmNum, out CmdNum);
//Debug.Log("Receive:" + MdmNum+"/"+CmdNum);
_packetProcesser.dispatchEvent(MdmNum, CmdNum, obj);
}

---------------------------------------------------------------------------
/// <summary>
/// 解析从网络收到的完整数据包
/// </summary>
/// <param name="buffer"></param>
/// 把处理过的网络数据解析一下
public object Parse(byte[] buffer, out int MdmNum,out int CmdNum)
{

List<byte> listBuffer = buffer.ToList();

List<byte> buf = new List<byte>();//取到前四位字节(版本号跟数据长度)
buf.AddRange(listBuffer.GetRange(0, 4));

MdmNum = listBuffer[5] << 8 | listBuffer[4];//获取主子消息号
CmdNum = listBuffer[7] << 8 | listBuffer[6];
#if UNITY_EDITOR
//GameTool.DebugProtoData(buffer, MdmNum, CmdNum,false);
#endif
List<byte> dataBuffer = new List<byte>();//获取消息数据
dataBuffer.AddRange(listBuffer.GetRange(8, listBuffer.Count - 8));

object obj = DataCenter.ProtobufUtility.Deserialize(dataBuffer.ToArray<byte>(), MdmNum, CmdNum); // 反序列化 Protobuf 对象
return obj;
}

5.根据协议号获取消息类型

public object Deserialize(byte[] data, int MdmNum, int CmdNum)
{
System.Type type = GetTypeByProtoNum(MdmNum, CmdNum);
if (type!=null)
{
using (MemoryStream m = new MemoryStream(data))
{
return ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(m, null, type);
}
}
return null;
}



public System.Type GetTypeByProtoNum(int MdmNum, int CmdNum)
{
foreach (var item in mProtobufType)
{
if (item.Key[0] == MdmNum && item.Key[1] == CmdNum)
{
return mProtobufType[item.Key];
}
}
Debug.LogError("找不到对应的协议,请检查对应协议监听的添加: " + MdmNum+"/"+ CmdNum);
return null;
}

------------------------------------------------------------------------------
//监听协议
public void AddEventListener(int MdmNum, int CmdNum, Type t, MessageListener listener)
{
List<int> d = new List<int>();
d.Add(MdmNum);
d.Add(CmdNum);
DataCenter.ProtobufUtility.mProtobufType.Add(d, t);

_client.AddEventListener(MdmNum, CmdNum, listener);
}
------------------------------------------------------------------------------
NetworkManager.GetInstance.AddEventListener(Protocol.S_LOBBY.MDM_H5, Protocol.S_LOBBY.CMD_H5.SUB_S_SHARE_RESULT, typeof(CMD_CP_ShareResult), ShareSuccessResponse);

6.执行对应的消息反馈 方法

private void ShareSuccessResponse(object obj)
{
Debug.Log("*******收到--分享成功--消息********");

var r = (CMD_CP_ShareResult)obj;
GameManager.GetInstance.ShareAwardList = r.props;
UIManager.GetInstance.AssignViewRender(EUiId.SettingView);
}

欢迎加入Unity业内qq交流群:956187480


版权声明

本文仅代表作者观点,不代表博信信息网立场。

热门