/// <summary> /// 对网络消息进行编码 /// </summary> /// <param name="netMsg">生成的消息</param> /// <returns>是否编码成功</returns> public bool EncodeMessage(ref UdpNetMessage netMsg) { netMsg.TS = Utility.Time.MillisecondTimeStamp(); if (netMsg.HeaderCode != UdpHeader.Hearbeat) { SendSN += 1; netMsg.SN = SendSN; } bool result = true; if (Conv != 0) { try { if (netMsg.Cmd == UdpProtocol.MSG) { sndMsgDict.TryAdd(netMsg.SN, netMsg); } } catch (Exception e) { Utility.Debug.LogError(e); } //若会话ID不为0,则缓存入ACK容器中,等接收成功后进行移除 ///* result=*/ ackMsgDict.TryAdd(netMsg.SN, netMsg); } return(result); }
/// <summary> /// 处理报文序号 /// </summary> /// <param name="netMsg">网络消息</param> protected void HandleMsgSN(UdpNetMessage netMsg) { //sn小于当前处理HandleSN则表示已经处理过的消息; if (netMsg.SN <= HandleSN) { return; } if (netMsg.SN - HandleSN > 1) { //对错序报文进行缓存 rcvMsgDict.TryAdd(netMsg.SN, netMsg); } HandleSN = netMsg.SN; #if DEBUG Utility.Debug.LogWarning($"Peer Conv:{Conv}, HandleMsgSN : {netMsg.ToString()}"); #endif if (netMsg.HeaderCode == UdpHeader.Message) { onReceiveDataHandler?.Invoke(Conv, new ArraySegment <byte>(netMsg.ServiceData)); } if (rcvMsgDict.TryRemove(HandleSN + 1, out var nxtNetMsg)) { #if DEBUG Utility.Debug.LogInfo($"HandleMsgSN Next KCP_MSG : {netMsg.ToString()}"); #endif HandleMsgSN(nxtNetMsg); } }
/// <summary> /// 处理进入这个peer的消息 /// </summary> /// <param name="service">udp服务</param> /// <param name="msg">消息体</param> public virtual void MessageHandler(INetworkMessage msg) { UdpNetMessage netMsg = msg as UdpNetMessage; switch (netMsg.Cmd) { //ACK报文 case UdpProtocol.ACK: { UdpNetMessage tmpMsg; if (sndMsgDict.TryRemove(netMsg.SN, out tmpMsg)) { #if DEBUG Utility.Debug.LogInfo($" Conv :{Conv},Receive KCP_ACK Message"); #endif CosmosEntry.ReferencePoolManager.Despawn(tmpMsg); } else { #if DEBUG if (netMsg.Conv != 0) { Utility.Debug.LogError($"Receive KCP_ACK Message Exception;SN : {netMsg.SN} "); } #endif } } break; case UdpProtocol.MSG: { #if DEBUG Utility.Debug.LogInfo($"Conv : {Conv} ,Receive KCP_MSG :{netMsg},消息体:{Utility.Converter.GetString(netMsg.ServiceData)}"); #endif //生成一个ACK报文,并返回发送 var ack = UdpNetMessage.ConvertToACK(netMsg); //这里需要发送ACK报文 sendMessageHandler?.Invoke(ack); if (netMsg.HeaderCode == UdpHeader.Hearbeat) { Heartbeat.OnRenewal(); #if DEBUG Utility.Debug.LogInfo($" Send KCP_ACK Message,conv :{Conv} ; {PeerEndPoint.Address} ;{PeerEndPoint.Port}"); #endif } else { //发送后进行原始报文数据的处理 HandleMsgSN(netMsg); } } break; case UdpProtocol.SYN: { //建立连接标志 Utility.Debug.LogInfo($"Conv : {netMsg.Conv} ,Receive KCP_SYN Message"); //生成一个ACK报文,并返回发送 var ack = UdpNetMessage.ConvertToACK(netMsg); //这里需要发送ACK报文 sendMessageHandler?.Invoke(ack); } break; case UdpProtocol.FIN: { //结束建立连接Cmd,这里需要谨慎考虑; Utility.Debug.LogError($"Conv : {Conv} ,Receive KCP_FIN Message"); var ack = UdpNetMessage.ConvertToACK(netMsg); //这里需要发送ACK报文 sendMessageHandler?.Invoke(ack); AbortConnection(); } break; } }