188 lines
4.9 KiB
C#
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);
|
|
}
|
|
|
|
}
|
|
} |