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

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
}
}