c1_unity/Assets/Scripts/Common/Network/TCPService/TCPConnection.Internal.cs
2023-04-03 11:04:31 +08:00

153 lines
3.9 KiB
C#

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
namespace BF
{
internal partial class TCPConnection
{
private readonly Dictionary<IPAddress, INetChannel> waitingConnectChannels;
private readonly List<INetChannel> verifyConnectedChannels;
private readonly NetSafeQueue<INetChannel> failedConnectedChannels = new NetSafeQueue<INetChannel>(8);
private void ConnectedChannelUpdate()
{
if (waitingConnectChannels.Count > 0)
{
return;
}
masterChannel?.Update();
}
private void WaitingConnectChannelUpdate()
{
if (waitingConnectChannels.Count <= 0)
{
return;
}
foreach (var channel in waitingConnectChannels)
{
channel.Value.Update();
}
}
private void VerifyConnectedChannelUpdate()
{
if (verifyConnectedChannels.Count <= 0)
{
return;
}
masterChannel = verifyConnectedChannels[0];
verifyConnectedChannels.Clear();
//clear other channel
foreach (var channel in waitingConnectChannels)
{
if (masterChannel == channel.Value)
{
continue;
}
channel.Value.Close();
}
waitingConnectChannels.Clear();
failedConnectedChannels.Clear();
}
internal void ChannelConnectVerifySuccess(INetChannel channel)
{
verifyConnectedChannels.Add(channel);
}
private void CreateDNSErrorMessage(string errorMsg)
{
dnsErrorMessage = new NetIncomingMessage(NetIncomingMessageType.ErrorMessage)
{
ErrorCode = NetErrorCode.DNSParseDomainNameError,
ErrorMsg = errorMsg,
};
}
private void FailedConnectedChannelUpdate()
{
if (waitingConnectChannels.Count <= 0)
{
return;
}
if (failedConnectedChannels.Count <= 0)
{
return;
}
while (failedConnectedChannels.Count > 0)
{
if (!failedConnectedChannels.TryDequeue(out var failedChannel))
{
continue;
}
TCPChannel channel = failedChannel as TCPChannel;
if (channel == null)
{
continue;
}
if (!waitingConnectChannels.ContainsKey(channel.RemoteEndPoint.Address))
{
continue;
}
if (waitingConnectChannels.Count <= 1)
{
continue;
}
var targetChannel = waitingConnectChannels[channel.RemoteEndPoint.Address];
waitingConnectChannels.Remove(channel.RemoteEndPoint.Address);
if (masterChannel == targetChannel)
{
masterChannel = waitingConnectChannels.Values.First();
}
targetChannel.Close();
}
}
/// <summary>
/// 创建连接的结果失败
/// </summary>
/// <param name="channel"></param>
internal void ChannelConnectVerifyFailed(INetChannel channel)
{
if (channel == null)
{
return;
}
failedConnectedChannels.Enqueue(channel);
}
#region MasterChannel
private void SetMasterChannel(TCPChannel channel)
{
if (masterChannel != null)
{
return;
}
masterChannel = channel;
}
#endregion
}
}