2023-04-03 11:04:31 +08:00

188 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace BF
{
internal partial class TCPConnection : INetConnection
{
private INetChannel masterChannel;
private NetIncomingMessage dnsErrorMessage = null;
internal readonly NetConnectConfiguration configuration;
public string UniqueIdentifier => configuration.UniqueIdentifier;
public NetConnectStatus ConnectStatus
{
get
{
var status = masterChannel.ConnectStatus;
return status;
}
}
public IPEndPoint IpEndPoint
{
get
{
var ip = masterChannel.RemoteEndPoint;
return ip;
}
}
public long ServerTimestamp
{
get
{
var serverTimestamp = masterChannel.ServerTimestamp;
return serverTimestamp;
}
}
public TCPConnection(NetConnectConfiguration configuration)
{
this.configuration = configuration;
waitingConnectChannels = new Dictionary<IPAddress, INetChannel>();
verifyConnectedChannels = new List<INetChannel>();
InitializeMessagePools();
}
~TCPConnection()
{
}
public void Update()
{
FailedConnectedChannelUpdate();
ConnectedChannelUpdate();
WaitingConnectChannelUpdate();
VerifyConnectedChannelUpdate();
}
public void Reconnect()
{
masterChannel?.Reconnect();
}
public void Connect(string domainName, int port)
{
IPAddress[] targetAddressList = null;
try
{
// TODO
// targetAddressList = Dns.GetHostEntry(domainName).AddressList;
targetAddressList = Dns.GetHostAddresses(domainName);
}
catch (SocketException socketException)
{
CreateDNSErrorMessage($"DNS parse domainName error : {socketException}");
return;
}
catch (Exception e)
{
CreateDNSErrorMessage($"DNS parse domainName error : {e}");
return;
}
if (targetAddressList == null || targetAddressList.Length <= 0)
{
CreateDNSErrorMessage($"DNS parse domainName error : address list is empty.");
return;
}
foreach (IPAddress ip in targetAddressList)
{
ConnectInternal(ip, port);
}
}
public void Connect(IPAddress ipAddress, int port)
{
ConnectInternal(ipAddress, port);
}
private void ConnectInternal(IPAddress ipAddress, int port)
{
bool isContains = waitingConnectChannels.ContainsKey(ipAddress);
//already contains
if (isContains)
{
return;
}
var remoteEndPoint = new IPEndPoint(ipAddress, port);
var channel = new TCPChannel(this, remoteEndPoint);
channel.Connect(ipAddress, port);
waitingConnectChannels.Add(ipAddress, channel);
//设置master channel
SetMasterChannel(channel);
}
public void Close()
{
masterChannel?.Close();
masterChannel = null;
if (waitingConnectChannels.Count <= 0)
{
return;
}
//clear all waiting connect channel
foreach (var channel in waitingConnectChannels)
{
channel.Value.Close();
}
waitingConnectChannels.Clear();
failedConnectedChannels.Clear();
}
public INetOutgoingMessage CreateMessage()
{
INetOutgoingMessage message = CreateOutgoingMessage(NetOutgoingMessageType.UserData);
return message;
}
public NetSendResult Send(INetOutgoingMessage message)
{
var result = masterChannel.Send(message);
return result;
}
public NetSendResult Send(uint group, byte cmd, byte[] data)
{
var result = masterChannel.Send(group, cmd, data);
return result;
}
public INetIncomingMessage ReadMessage()
{
INetIncomingMessage message = null;
if (dnsErrorMessage != null)
{
message = dnsErrorMessage;
dnsErrorMessage = null;
return message;
}
message = masterChannel.ReadMessage();
return message;
}
public void RecycleMessage(INetIncomingMessage message)
{
Recycle((NetIncomingMessage)message);
}
}
}