298 lines
9.3 KiB
C#
298 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
|
|
namespace BF
|
|
{
|
|
internal partial class TCPChannelService
|
|
{
|
|
private readonly Dictionary<string, INetConnection> connections = new Dictionary<string, INetConnection>();
|
|
|
|
private bool quitFlag = false;
|
|
private readonly ManualResetEvent quitEvent = new ManualResetEvent(false);
|
|
|
|
private void NetworkLoop()
|
|
{
|
|
while (!quitFlag)
|
|
{
|
|
WaitHandle.WaitAny(new WaitHandle[] { quitEvent}, 2);
|
|
|
|
UpdateAsyncCommandMethod();
|
|
|
|
UpdateConnections();
|
|
}
|
|
|
|
Debug.LogWarning($"{configuration.ThreadName} thread quit !!!");
|
|
}
|
|
|
|
private void UpdateConnections()
|
|
{
|
|
foreach (var connection in connections)
|
|
{
|
|
connection.Value.Update();
|
|
}
|
|
}
|
|
|
|
private void UpdateAsyncCommandMethod()
|
|
{
|
|
try
|
|
{
|
|
while (commandMethodQueue.TryDequeue(out var currentMethod))
|
|
{
|
|
AsyncCommandMethodExecute(currentMethod);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
mainThreadResetEvent.Set();
|
|
|
|
Debug.LogException(exception);
|
|
}
|
|
}
|
|
|
|
private void AsyncCommandMethodExecute(BaseCommandMethod currentMethod)
|
|
{
|
|
switch (currentMethod.Command)
|
|
{
|
|
case CommandCategory.Shutdown:
|
|
{
|
|
ShutdownAllConnections();
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.ConnectDomainName:
|
|
{
|
|
var method = currentMethod as ConnectDomainNameMethod;
|
|
ConnectInternal(method.Configuration, method.DomainName, method.Port);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.ConnectIPAddress:
|
|
{
|
|
var method = currentMethod as ConnectIPAddressMethod;
|
|
ConnectInternal(method.Configuration, method.IpAddress, method.Port);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.Reconnect:
|
|
{
|
|
var method = currentMethod as ReconnectMethod;
|
|
ReconnectInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.Close:
|
|
{
|
|
var method = currentMethod as CloseMethod;
|
|
CloseInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.GetConnectStatus:
|
|
{
|
|
var method = currentMethod as GetConnectStatusMethod;
|
|
method.Result = GetConnectStatusInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.CreateMessage:
|
|
{
|
|
var method = currentMethod as CreateMessageMethod;
|
|
method.Result = CreateMessageInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.SendMessage:
|
|
{
|
|
var method = currentMethod as SendMessageMethod;
|
|
method.Result = SendInternal(method.UniqueIdentifier, method.Message);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.SendRaw:
|
|
{
|
|
var method = currentMethod as SendRawMethod;
|
|
method.Result = SendInternal(method.UniqueIdentifier, method.Group, method.CMD, method.Data);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.ReadMessage:
|
|
{
|
|
var method = currentMethod as ReadMessageMethod;
|
|
method.Result = ReadMessageInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.RecycleMessage:
|
|
{
|
|
var method = currentMethod as RecycleMessageMethod;
|
|
RecycleMessageInternal(method.UniqueIdentifier, method.Message);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.GetConnectIP:
|
|
{
|
|
var method = currentMethod as GetConnectIPMethod;
|
|
method.Result = GetConnectIPInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
case CommandCategory.GetServerTimestamp:
|
|
{
|
|
var method = currentMethod as GetConnectServerTimestampMethod;
|
|
method.Result = GetConnectServerTimestampInternal(method.UniqueIdentifier);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
mainThreadResetEvent.Set();
|
|
}
|
|
|
|
#region Internal Method
|
|
|
|
private void ConnectInternal(NetConnectConfiguration configuration, string domainName, int port)
|
|
{
|
|
INetConnection connection = GetConnection(configuration.UniqueIdentifier);
|
|
if (connection != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
connection = new TCPConnection(configuration);
|
|
connection.Connect(domainName, port);
|
|
AddConnection(configuration.UniqueIdentifier, connection);
|
|
}
|
|
|
|
private void ConnectInternal(NetConnectConfiguration configuration, IPAddress ipAddress, int port)
|
|
{
|
|
INetConnection connection = GetConnection(configuration.UniqueIdentifier);
|
|
if (connection != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
connection = new TCPConnection(configuration);
|
|
connection.Connect(ipAddress, port);
|
|
AddConnection(configuration.UniqueIdentifier, connection);
|
|
}
|
|
|
|
private void ReconnectInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
connection?.Reconnect();
|
|
}
|
|
|
|
private void CloseInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
connection?.Close();
|
|
RemoveConnection(uniqueIdentifier);
|
|
}
|
|
|
|
private NetConnectStatus GetConnectStatusInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
if (connection != null)
|
|
{
|
|
return connection.ConnectStatus;
|
|
}
|
|
|
|
return NetConnectStatus.InvalidConnect;
|
|
}
|
|
|
|
private string GetConnectIPInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
if (connection == null)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
if (connection.IpEndPoint == null)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
return connection.IpEndPoint.Address.ToString();
|
|
}
|
|
|
|
private long GetConnectServerTimestampInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
if (connection == null)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return connection.ServerTimestamp;
|
|
}
|
|
|
|
private INetOutgoingMessage CreateMessageInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
return connection?.CreateMessage();
|
|
}
|
|
|
|
private NetSendResult SendInternal(string uniqueIdentifier, INetOutgoingMessage message)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
return connection.Send(message);
|
|
}
|
|
|
|
private NetSendResult SendInternal(string uniqueIdentifier, uint group, byte cmd, byte[] data)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
return connection.Send(group, cmd, data);
|
|
}
|
|
|
|
private INetIncomingMessage ReadMessageInternal(string uniqueIdentifier)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
return connection?.ReadMessage();
|
|
}
|
|
|
|
private void RecycleMessageInternal(string uniqueIdentifier, INetIncomingMessage message)
|
|
{
|
|
INetConnection connection = GetConnection(uniqueIdentifier);
|
|
connection?.RecycleMessage(message);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Utility
|
|
|
|
private INetConnection GetConnection(string uniqueIdentifier)
|
|
{
|
|
connections.TryGetValue(uniqueIdentifier, out var connection);
|
|
return connection;
|
|
}
|
|
|
|
private void AddConnection(string uniqueIdentifier, INetConnection connection)
|
|
{
|
|
connections.Add(uniqueIdentifier, connection);
|
|
}
|
|
|
|
private void RemoveConnection(string uniqueIdentifier)
|
|
{
|
|
connections.Remove(uniqueIdentifier);
|
|
}
|
|
|
|
private void ShutdownAllConnections()
|
|
{
|
|
foreach (var connection in connections)
|
|
{
|
|
connection.Value.Close();
|
|
}
|
|
|
|
connections.Clear();
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
} |