271 lines
8.3 KiB
C#
271 lines
8.3 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Net;
|
||
|
||
namespace BF
|
||
{
|
||
/// <summary>
|
||
/// 单例
|
||
///
|
||
/// </summary>
|
||
public sealed class NetClient
|
||
{
|
||
private readonly Dictionary<NetServiceType, INetChannelService> channelServices = new Dictionary<NetServiceType, INetChannelService>(new NetServiceTypeComparer());
|
||
private readonly Dictionary<string, INetChannelService> loopUpServiceDic = new Dictionary<string, INetChannelService>();
|
||
/// <summary>
|
||
/// init reference count +1
|
||
/// shutdown reference count -1
|
||
/// if reference count less equals 0 will actually shutdown all service
|
||
/// </summary>
|
||
private int referenceCount;
|
||
|
||
#region Instance
|
||
|
||
public static NetClient Instance
|
||
{
|
||
get { return Nested.instance; }
|
||
}
|
||
|
||
private NetClient()
|
||
{ }
|
||
|
||
private class Nested
|
||
{
|
||
internal static readonly NetClient instance = new NetClient();
|
||
|
||
static Nested()
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
public void Init()
|
||
{
|
||
referenceCount++;
|
||
}
|
||
|
||
public void Start()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭NetClient,会关闭所有连接,释放所有资源
|
||
/// </summary>
|
||
public void Shutdown()
|
||
{
|
||
referenceCount--;
|
||
if (referenceCount > 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
foreach (var channelService in channelServices)
|
||
{
|
||
channelService.Value.Shutdown();
|
||
}
|
||
|
||
channelServices.Clear();
|
||
loopUpServiceDic.Clear();
|
||
}
|
||
|
||
public void SetupService(NetConfiguration configuration)
|
||
{
|
||
if (ContainChannelService(configuration.ServiceType))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var service = CreateService(configuration);
|
||
channelServices.Add(service.ServiceType, service);
|
||
}
|
||
|
||
public void Connect(NetConnectConfiguration configuration, string domainName, int port)
|
||
{
|
||
if (loopUpServiceDic.ContainsKey(configuration.UniqueIdentifier))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var service = GetChannelService(configuration.ServiceType);
|
||
service.Connect(configuration, domainName, port);
|
||
loopUpServiceDic.Add(configuration.UniqueIdentifier, service);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建新的连接,和Close是对应的概念
|
||
/// </summary>
|
||
/// <param name="configuration"></param>
|
||
/// <param name="ipAddress"></param>
|
||
/// <param name="port"></param>
|
||
public void Connect(NetConnectConfiguration configuration, IPAddress ipAddress, int port)
|
||
{
|
||
if (loopUpServiceDic.ContainsKey(configuration.UniqueIdentifier))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var service = GetChannelService(configuration.ServiceType);
|
||
service.Connect(configuration, ipAddress, port);
|
||
loopUpServiceDic.Add(configuration.UniqueIdentifier, service);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 手动开始重连,使用手动重连,必须关闭自动重连
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier"></param>
|
||
public void Reconnect(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
service?.Reconnect(uniqueIdentifier);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭Connect创建的连接,释放连接使用的资源;关闭后不可以再次使用此连接
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier"></param>
|
||
public void Close(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
service?.Close(uniqueIdentifier);
|
||
loopUpServiceDic.Remove(uniqueIdentifier);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂时不公有
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier"></param>
|
||
/// <returns></returns>
|
||
internal INetOutgoingMessage CreateMessage(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
return service?.CreateMessage(uniqueIdentifier);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂时不公有
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier"></param>
|
||
/// <returns></returns>
|
||
internal NetSendResult Send(string uniqueIdentifier, INetOutgoingMessage message)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
return service.Send(uniqueIdentifier, message);
|
||
}
|
||
|
||
public NetSendResult Send(string uniqueIdentifier, uint group, byte cmd, byte[] data)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
return service.Send(uniqueIdentifier, group, cmd, data);
|
||
}
|
||
|
||
public INetIncomingMessage ReadMessage(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
return service?.ReadMessage(uniqueIdentifier);
|
||
}
|
||
|
||
public void RecycleMessage(string uniqueIdentifier, INetIncomingMessage message)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
service?.RecycleMessage(uniqueIdentifier, message);
|
||
}
|
||
|
||
public NetConnectStatus GetConnectStatus(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
if (service == null)
|
||
{
|
||
return NetConnectStatus.InvalidConnect;
|
||
}
|
||
|
||
return service.GetConnectStatus(uniqueIdentifier);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定连接的服务器地址
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier">连接id</param>
|
||
/// <returns>连接的远程服务器地址</returns>
|
||
public string GetConnectIP(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
if(service == null)
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
return service.GetConnectIP(uniqueIdentifier);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定连接的UGate服务器时间戳;此时间戳,是上一次心跳包同步的;
|
||
/// 注意:必须在连接状态下才可以获取到有效同步时间
|
||
/// </summary>
|
||
/// <param name="uniqueIdentifier">连接id</param>
|
||
/// <returns>由心跳包同步的UGate服务器时间戳</returns>
|
||
public long GetServerTimestamp(string uniqueIdentifier)
|
||
{
|
||
var service = GetChannelService(uniqueIdentifier);
|
||
if(service == null)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
return service.GetConnectServerTimestamp(uniqueIdentifier);
|
||
}
|
||
|
||
private bool ContainChannelService(NetServiceType serviceType)
|
||
{
|
||
return channelServices.ContainsKey(serviceType);
|
||
}
|
||
|
||
private INetChannelService GetChannelService(NetServiceType serviceType)
|
||
{
|
||
if (!channelServices.TryGetValue(serviceType, out INetChannelService service))
|
||
{
|
||
throw new NotImplementedException($"{serviceType} not support.");
|
||
}
|
||
|
||
return service;
|
||
}
|
||
|
||
private INetChannelService GetChannelService(string uniqueIdentifier)
|
||
{
|
||
if (!loopUpServiceDic.TryGetValue(uniqueIdentifier, out INetChannelService service))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
return service;
|
||
}
|
||
|
||
private INetChannelService CreateService(NetConfiguration configuration)
|
||
{
|
||
INetChannelService service = null;
|
||
switch (configuration.ServiceType)
|
||
{
|
||
case NetServiceType.TCPService:
|
||
service = new TCPChannelService();
|
||
break;
|
||
|
||
case NetServiceType.UDPService:
|
||
throw new NotImplementedException();
|
||
|
||
case NetServiceType.WebsocketService:
|
||
throw new NotImplementedException();
|
||
|
||
default:
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
service.Start(configuration);
|
||
|
||
return service;
|
||
}
|
||
|
||
}
|
||
}
|