/// <summary> /// 非空虚函数; /// 发送报文信息; /// 发送给特定的endpoint对象,可不局限于一个服务器点; /// </summary> /// <param name="netMsg">消息体</param> /// <param name="endPoint">远程对象</param> public virtual async void SendMessage(INetworkMessage netMsg, IPEndPoint endPoint) { if (!Available) { return; } UdpNetworkMessage udpNetMsg = netMsg as UdpNetworkMessage; udpNetMsg.Conv = Conv; Utility.Debug.LogInfo($"发送网络消息 : Conv : {udpNetMsg.Conv} ; Cmd {udpNetMsg.Cmd} ; OperationCode:{udpNetMsg.OperationCode}"); if (udpSocket != null) { try { var buffer = udpNetMsg.GetBuffer(); int length = await udpSocket.SendAsync(buffer, buffer.Length, endPoint); if (length != buffer.Length) { //消息未完全发送,则重新发送 SendMessage(udpNetMsg, endPoint); } } catch (Exception e) { Utility.Debug.LogError($"发送异常:{e.Message}"); } } }
/// <summary> /// 对网络消息进行编码 /// </summary> /// <param name="netMsg">生成的消息</param> /// <returns>是否编码成功</returns> public bool EncodeMessage(ref UdpNetworkMessage netMsg) { netMsg.TS = Utility.Time.MillisecondTimeStamp(); SendSN += 1; netMsg.SN = SendSN; netMsg.Conv = Conv; netMsg.EncodeMessage(); bool result = true; if (Conv != 0) { //若会话ID不为0,则缓存入ACK容器中,等接收成功后进行移除 /* result =*/ //ackMsgDict.TryAdd(netMsg.SN, netMsg); try { if (netMsg.Cmd == KcpProtocol.MSG) { ackMsgDict.TryAdd(netMsg.SN, netMsg); } } catch (Exception e) { Utility.Debug.LogError(e); } } return(result); }
/// <summary> /// 处理报文序号 /// </summary> /// <param name="netMsg">网络消息</param> protected void HandleMsgSN(UdpNetworkMessage netMsg) { //sn小于当前处理HandleSN则表示已经处理过的消息; if (netMsg.SN <= HandleSN) { return; } if (netMsg.SN - HandleSN > 1) { //对错序报文进行缓存 ackMsgDict.TryAdd(netMsg.SN, netMsg); } HandleSN = netMsg.SN; //将消息分发到各个监听网络事件的模块中 NetworkEventCore.Instance.Dispatch(netMsg.OperationCode, netMsg); if (Conv != netMsg.Conv) { Conv = netMsg.Conv; } UdpNetworkMessage nxtNetMsg; if (ackMsgDict.TryRemove(HandleSN + 1, out nxtNetMsg)) { HandleMsgSN(nxtNetMsg); } }
void SendClick() { string str = inputMsg.text; var data = Utility.Encode.ConvertToByte(str); UdpNetworkMessage msg = new UdpNetworkMessage(0, 0, KcpProtocol.MSG, 0, data); Facade.SendNetworkMessage(msg); }
/// <summary> /// 处理进入这个peer的消息; /// 由service分发消息到这个方法; /// </summary> /// <param name="msg">消息体</param> public virtual void MessageHandler(INetworkMessage msg) { UdpNetworkMessage netMsg = msg as UdpNetworkMessage; switch (netMsg.Cmd) { //ACK报文 case KcpProtocol.ACK: { if (netMsg.OperationCode == NetworkOpCode._Heartbeat) { Heartbeat.OnRenewal(); } UdpNetworkMessage tmpMsg; if (ackMsgDict.TryRemove(netMsg.SN, out tmpMsg)) { Utility.Debug.LogInfo($" Conv :{Conv},接收到ACK消息 "); } else { if (netMsg.Conv != 0) { Utility.Debug.LogError($"接收网络ACK消息异常;SN : {netMsg.SN} "); } } } break; case KcpProtocol.MSG: { Utility.Debug.LogInfo($"Conv : {Conv} ,接收到MSG消息"); //生成一个ACK报文,并返回发送 var ack = UdpNetworkMessage.ConvertToACK(netMsg); //这里需要发送ACK报文 sendMessageHandler?.Invoke(ack); //发送后进行原始报文数据的处理 HandleMsgSN(netMsg); Utility.Debug.LogInfo($"发送ACK报文,conv :{Conv} ; {PeerEndPoint.Address} ;{PeerEndPoint.Port}"); //if (netMsg.OperationCode == NetworkOpCode._Heartbeat) // Heartbeat.OnRenewal(); //else NetworkEventCore.Instance.Dispatch(netMsg.OperationCode, netMsg); } Utility.Debug.LogInfo($"当前消息缓存数量为:{ackMsgDict.Count} ; Peer conv : {Conv}"); break; case KcpProtocol.SYN: { //建立连接标志 Utility.Debug.LogInfo($"Conv : {Conv} ,接收到SYN消息"); //生成一个ACK报文,并返回发送 var ack = UdpNetworkMessage.ConvertToACK(netMsg); //这里需要发送ACK报文 sendMessageHandler?.Invoke(ack); } break; case KcpProtocol.FIN: { //结束建立连接Cmd,这里需要谨慎考虑; Utility.Debug.LogWarning($"Conv : {Conv} ,接收到FIN消息"); OnDeactive(); Facade.NetworkDisconnect(); //TODO KcpProtocol.FIN 内部耦合 Facade.NetworkDisconnect(); } break; } Facade.DespawnReference(netMsg); }