using System; using System.Net; using System.Net.Sockets; namespace BF { internal partial class TCPChannel : INetChannel { private readonly NetChannelMessageService messageService; private readonly TCPConnection ownerConnection; /// /// internal actual status /// private NetConnectStatus actualStatus; /// /// visible connect status /// private NetConnectStatus visibleStatus; private bool decoding = false; public NetConnectStatus ConnectStatus { get { return connectContext == NetConnectContext.Reconnect ? NetConnectStatus.Reconnecting : visibleStatus; } } /// /// 最近一个心跳包同步的服务器当前时间戳 ms /// public long ServerTimestamp => serverTimestamp; public TCPChannel(TCPConnection ownerConnection, IPEndPoint endPoint) { this.ownerConnection = ownerConnection; messageService = new NetChannelMessageService(); InitializeReceive(); InitializeSend(); InitializeConnect(endPoint); InitializeHeartBeat(); InitializeReconnect(); #if BF_DEBUG NetStatistics.RegisterConnect(ownerConnection.UniqueIdentifier, o => { if (o is NetOutgoingMessage tempMessage) { sendMessageQueue.Enqueue(tempMessage); } }, o => { if (o is NetIncomingMessage tempMessage) { receiveMessageQueue.Enqueue(tempMessage); } }); #endif } public void Update() { if (visibleStatus == NetConnectStatus.Unconnected) { return; } // BFLog.Log("visibleStatus = " + visibleStatus); if (visibleStatus == NetConnectStatus.Decoding && !decoding) { if(ownerConnection.UniqueIdentifier.CompareTo(BF.NetManager.MAIN_SOCKET_NAME) == 0) { bool decodeFinish = BF.BFMain.Instance.NetMgr.GetDecodeStataus(); if (decodeFinish) { uint group = BF.BFMain.Instance.NetMgr.GetDecodeGroup(); if (group == Auth_Rsp_Group) { decoding = true; FilterAuthIncomingMessage2(); return; } } } else { bool decodeFinish = BF.BFMain.Instance.NetMgr.GetDecodeChatStataus(); if (decodeFinish) { uint group = BF.BFMain.Instance.NetMgr.GetDecodeChatGroup(); if (group == Chat_Auth_Rsp_Group) { decoding = true; FilterAuthIncomingMessage2(); return; } } } } // BFLog.Log("visibleStatus = " + visibleStatus + "decoding = " + decoding); if (visibleStatus == NetConnectStatus.Decoding2 && !decoding) { if(ownerConnection.UniqueIdentifier.CompareTo(BF.NetManager.MAIN_SOCKET_NAME) == 0) { bool decodeFinish = BF.BFMain.Instance.NetMgr.GetDecodeStataus(); if (decodeFinish) { uint group = BF.BFMain.Instance.NetMgr.GetDecodeGroup(); if (group == Reconnect_Rsp_Group) { decoding = true; FilterReconnectIncomingMessage2(); return; } } } else { bool decodeFinish = BF.BFMain.Instance.NetMgr.GetDecodeChatStataus(); if (decodeFinish) { uint group = BF.BFMain.Instance.NetMgr.GetDecodeChatGroup(); if (group == Reconnect_Rsp_Group) { decoding = true; FilterReconnectIncomingMessage2(); return; } } } } try { SendUpdate(); ReceiveUpdate(); HeartBeat(); // UpdateTimer(); // UpdateSmartReconnect(); } catch (Exception e) { LogError(NetErrorCode.ExceptionError, $"Channel update throw exception : {e}"); } } public void Reconnect() { if (actualStatus != NetConnectStatus.Disconnected && actualStatus != NetConnectStatus.Connected) { return; } internalReconnectFlag = false; LogDebug($"Begin force reconnect : {tryReconnectCount}"); PrepareReconnect(); TryConnectNewConnect(); } public void Connect(IPAddress ipAddress, int port) { ConnectInternalAsync(); } public void Close() { #if BF_DEBUG NetStatistics.UnRegisterConnect(ownerConnection.UniqueIdentifier); #endif Disconnect(); waitingSendMessagesQueue.Clear(); alreadySendMessagesQueue.Clear(); alreadySendExchangeStack.Clear(); serverDisconnectMessageQueue.Clear(); ClearSendReceiveMessageQueue(); SetConnectContext(NetConnectContext.Invalid); SetActualStatus(NetConnectStatus.Unconnected); SetVisibleStatus(NetConnectStatus.Unconnected); receiveBuffer.Dispose(); sendStream.Dispose(); } public NetSendResult Send(INetOutgoingMessage message) { var result = SendInternal((NetOutgoingMessage)message); return result; } public NetSendResult Send(uint group, byte cmd, byte[] data) { var outgoingMessage = ownerConnection.CreateOutgoingMessage(NetOutgoingMessageType.UserData); outgoingMessage.Encode(group, cmd, data); var result = SendInternal(outgoingMessage); return result; } public INetIncomingMessage ReadMessage() { NetIncomingMessage message = null; releasedIncomingMessage.TryDequeue(out message); return message; } } }