184 lines
5.5 KiB
C#
184 lines
5.5 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
namespace BF
|
|
{
|
|
internal partial class TCPChannel : INetChannel
|
|
{
|
|
private readonly NetChannelMessageService messageService;
|
|
private readonly TCPConnection ownerConnection;
|
|
|
|
/// <summary>
|
|
/// internal actual status
|
|
/// </summary>
|
|
private NetConnectStatus actualStatus;
|
|
|
|
/// <summary>
|
|
/// visible connect status
|
|
/// </summary>
|
|
private NetConnectStatus visibleStatus;
|
|
private bool decoding = false;
|
|
|
|
public NetConnectStatus ConnectStatus
|
|
{
|
|
get
|
|
{
|
|
return connectContext == NetConnectContext.Reconnect ? NetConnectStatus.Reconnecting : visibleStatus;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 最近一个心跳包同步的服务器当前时间戳 ms
|
|
/// </summary>
|
|
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)
|
|
{
|
|
bool decodeFinish = BF.BFMain.Instance.NetMgr.GetDecodeStataus();
|
|
if (decodeFinish)
|
|
{
|
|
uint group = BF.BFMain.Instance.NetMgr.GetDecodeGroup();
|
|
if (group == Auth_Rsp_Group || group == Chat_Auth_Rsp_Group)
|
|
{
|
|
decoding = true;
|
|
FilterAuthIncomingMessage2();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// BFLog.Log("visibleStatus = " + visibleStatus + "decoding = " + decoding);
|
|
if (visibleStatus == NetConnectStatus.Decoding2 && !decoding)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |