using System; using System.Collections.Generic; using System.Net; namespace BF { /// /// 单例 /// /// public sealed class NetClient { private readonly Dictionary channelServices = new Dictionary(new NetServiceTypeComparer()); private readonly Dictionary loopUpServiceDic = new Dictionary(); /// /// init reference count +1 /// shutdown reference count -1 /// if reference count less equals 0 will actually shutdown all service /// 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() { } /// /// 关闭NetClient,会关闭所有连接,释放所有资源 /// 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); } /// /// 创建新的连接,和Close是对应的概念 /// /// /// /// 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); } /// /// 手动开始重连,使用手动重连,必须关闭自动重连 /// /// public void Reconnect(string uniqueIdentifier) { var service = GetChannelService(uniqueIdentifier); service?.Reconnect(uniqueIdentifier); } /// /// 关闭Connect创建的连接,释放连接使用的资源;关闭后不可以再次使用此连接 /// /// public void Close(string uniqueIdentifier) { var service = GetChannelService(uniqueIdentifier); service?.Close(uniqueIdentifier); loopUpServiceDic.Remove(uniqueIdentifier); } /// /// 暂时不公有 /// /// /// internal INetOutgoingMessage CreateMessage(string uniqueIdentifier) { var service = GetChannelService(uniqueIdentifier); return service?.CreateMessage(uniqueIdentifier); } /// /// 暂时不公有 /// /// /// 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); } /// /// 获取指定连接的服务器地址 /// /// 连接id /// 连接的远程服务器地址 public string GetConnectIP(string uniqueIdentifier) { var service = GetChannelService(uniqueIdentifier); if(service == null) { return string.Empty; } return service.GetConnectIP(uniqueIdentifier); } /// /// 获取指定连接的UGate服务器时间戳;此时间戳,是上一次心跳包同步的; /// 注意:必须在连接状态下才可以获取到有效同步时间 /// /// 连接id /// 由心跳包同步的UGate服务器时间戳 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; } } }