//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Threading; using TouchSocket.Core; using TouchSocket.Resources; namespace TouchSocket.Sockets { /// /// TCP泛型服务器,由客户自己指定类型。 /// public class TcpService : TcpServiceBase, ITcpService where TClient : SocketClient { /// /// 构造函数 /// public TcpService() { m_socketClients = new SocketClientCollection(); m_getDefaultNewID = () => { return Interlocked.Increment(ref m_nextId).ToString(); }; } #region 变量 private readonly SocketClientCollection m_socketClients; private int m_backlog; private TouchSocketConfig m_config; private Func m_getDefaultNewID; private int m_maxCount; private NetworkMonitor[] m_monitors; private long m_nextId; private ReceiveType m_receiveType; private ServerState m_serverState; private bool m_usePlugin; private bool m_useSsl; #endregion 变量 #region 属性 /// /// 获取服务器配置 /// public override TouchSocketConfig Config => m_config; /// /// /// public override IContainer Container => Config?.Container; /// /// /// public override Func GetDefaultNewID => m_getDefaultNewID; /// /// /// public override int MaxCount => m_maxCount; /// /// /// public override NetworkMonitor[] Monitors => m_monitors; /// /// /// public override IPluginsManager PluginsManager => Config?.PluginsManager; /// /// /// public override string ServerName => Config?.GetValue(TouchSocketConfigExtension.ServerNameProperty); /// /// /// public override ServerState ServerState => m_serverState; /// /// /// public override SocketClientCollection SocketClients => m_socketClients; /// /// /// public override bool UsePlugin => m_usePlugin; /// /// /// public override bool UseSsl => m_useSsl; #endregion 属性 #region 事件 /// /// 用户连接完成 /// public TouchSocketEventHandler Connected { get; set; } /// /// 有用户连接的时候 /// public OperationEventHandler Connecting { get; set; } /// /// 有用户断开连接 /// public DisconnectEventHandler Disconnected { get; set; } /// /// 即将断开连接(仅主动断开时有效)。 /// /// 当主动调用Close断开时,可通过终止断开行为。 /// /// public DisconnectEventHandler Disconnecting { get; set; } /// /// 当客户端ID被修改时触发。 /// public IDChangedEventHandler IDChanged { get; set; } /// /// /// /// /// protected override sealed void OnClientConnected(ISocketClient socketClient, TouchSocketEventArgs e) { OnConnected((TClient)socketClient, e); } /// /// /// /// /// protected override sealed void OnClientConnecting(ISocketClient socketClient, OperationEventArgs e) { OnConnecting((TClient)socketClient, e); } /// /// /// /// /// protected override sealed void OnClientDisconnected(ISocketClient socketClient, DisconnectEventArgs e) { OnDisconnected((TClient)socketClient, e); } /// /// /// /// /// protected override sealed void OnClientDisconnecting(ISocketClient socketClient, DisconnectEventArgs e) { OnDisconnecting((TClient)socketClient, e); } /// /// /// /// /// /// protected override sealed void OnClientReceivedData(ISocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) { OnReceived((TClient)socketClient, byteBlock, requestInfo); } /// /// 客户端连接完成,覆盖父类方法将不会触发事件。 /// /// /// protected virtual void OnConnected(TClient socketClient, TouchSocketEventArgs e) { Connected?.Invoke(socketClient, e); } /// /// 客户端请求连接,覆盖父类方法将不会触发事件。 /// /// /// protected virtual void OnConnecting(TClient socketClient, OperationEventArgs e) { Connecting?.Invoke(socketClient, e); } /// /// 客户端断开连接,覆盖父类方法将不会触发事件。 /// /// /// protected virtual void OnDisconnected(TClient socketClient, DisconnectEventArgs e) { Disconnected?.Invoke(socketClient, e); } /// /// 即将断开连接(仅主动断开时有效)。 /// /// 当主动调用Close断开时,可通过终止断开行为。 /// /// /// /// protected virtual void OnDisconnecting(TClient socketClient, DisconnectEventArgs e) { Disconnecting?.Invoke(socketClient, e); } /// /// 当收到适配器数据。 /// /// /// /// protected virtual void OnReceived(TClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) { } #endregion 事件 /// /// /// public override void Clear() { string[] ids = GetIDs(); foreach (var item in ids) { if (TryGetSocketClient(item, out TClient client)) { client.Dispose(); } } } /// /// 获取当前在线的所有客户端 /// /// public TClient[] GetClients() { var clients = m_socketClients.GetClients().ToArray(); TClient[] clients1 = new TClient[clients.Length]; for (int i = 0; i < clients.Length; i++) { clients1[i] = (TClient)clients[i]; } return clients1; } /// /// /// /// /// /// /// public override void ResetID(string oldID, string newID) { if (string.IsNullOrEmpty(oldID)) { throw new ArgumentException($"“{nameof(oldID)}”不能为 null 或空。", nameof(oldID)); } if (string.IsNullOrEmpty(newID)) { throw new ArgumentException($"“{nameof(newID)}”不能为 null 或空。", nameof(newID)); } if (oldID == newID) { return; } if (m_socketClients.TryGetSocketClient(oldID, out TClient socketClient)) { socketClient.ResetID(newID); } else { throw new ClientNotFindException(TouchSocketStatus.ClientNotFind.GetDescription(oldID)); } } /// /// /// /// public override IService Setup(TouchSocketConfig config) { m_config = config; if (config.IsUsePlugin) { PluginsManager.Raise(nameof(IConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config)); } LoadConfig(m_config); if (UsePlugin) { PluginsManager.Raise(nameof(IConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config)); } Container.RegisterTransient(); return this; } /// /// /// /// public override IService Setup(int port) { TouchSocketConfig serviceConfig = new TouchSocketConfig(); serviceConfig.SetListenIPHosts(new IPHost[] { new IPHost(port) }); return Setup(serviceConfig); } /// /// /// /// /// public override bool SocketClientExist(string id) { return SocketClients.SocketClientExist(id); } /// /// /// /// /// /// public override IService Start() { try { IPHost[] iPHosts = Config.GetValue(TouchSocketConfigExtension.ListenIPHostsProperty); if (iPHosts == null || iPHosts.Length == 0) { throw new Exception("IPHosts为空,无法绑定"); } switch (m_serverState) { case ServerState.None: { BeginListen(iPHosts); break; } case ServerState.Running: { return this; } case ServerState.Stopped: { BeginListen(iPHosts); break; } case ServerState.Disposed: { throw new Exception("无法重新利用已释放对象"); } } m_serverState = ServerState.Running; if (UsePlugin) { PluginsManager.Raise(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, default)); } return this; } catch (Exception ex) { m_serverState = ServerState.Exception; if (UsePlugin) { PluginsManager.Raise(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, ex) { Message=ex.Message }); } throw; } } /// /// /// public override IService Stop() { if (m_monitors != null) { foreach (var item in m_monitors) { item.Socket?.Dispose(); } } m_monitors = null; Clear(); m_serverState = ServerState.Stopped; if (UsePlugin) { PluginsManager.Raise(nameof(IServicePlugin.OnStoped), this, new ServiceStateEventArgs(this.m_serverState, default)); } return this; } /// /// 尝试获取TClient /// /// ID /// TClient /// public bool TryGetSocketClient(string id, out TClient socketClient) { return m_socketClients.TryGetSocketClient(id, out socketClient); } /// /// /// /// protected override void Dispose(bool disposing) { if (!DisposedValue) { if (disposing) { if (m_monitors != null) { foreach (var item in m_monitors) { item.Socket?.Dispose(); } m_monitors = null; } Clear(); m_serverState = ServerState.Disposed; if (UsePlugin) { PluginsManager.Raise(nameof(IServicePlugin.OnStoped), this, new ServiceStateEventArgs(this.m_serverState, default)); } PluginsManager.Clear(); } } base.Dispose(disposing); } /// /// 初始化客户端实例,默认实现为 /// /// protected virtual TClient GetClientInstence() { return Container.Resolve(); } /// /// 加载配置 /// /// protected virtual void LoadConfig(TouchSocketConfig config) { if (config == null) { throw new Exception("配置文件为空"); } if (config.GetValue(TouchSocketConfigExtension.GetDefaultNewIDProperty) is Func fun) { m_getDefaultNewID = fun; } m_usePlugin = config.IsUsePlugin; m_maxCount = config.GetValue(TouchSocketConfigExtension.MaxCountProperty); m_backlog = config.GetValue(TouchSocketConfigExtension.BacklogProperty); BufferLength = config.GetValue(TouchSocketConfigExtension.BufferLengthProperty); m_receiveType = config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty); Logger ??= Container.Resolve(); if (config.GetValue(TouchSocketConfigExtension.SslOptionProperty) != null) { m_useSsl = true; } } /// /// 在验证Ssl发送错误时。 /// /// protected virtual void OnAuthenticatingError(System.Exception ex) { } /// /// 在Socket初始化对象后,Bind之前调用。 /// 可用于设置Socket参数。 /// 父类方法可覆盖。 /// /// protected virtual void PreviewBind(Socket socket) { } private void Args_Completed(object sender, SocketAsyncEventArgs e) { if (e.LastOperation == SocketAsyncOperation.Accept) { OnAccepted(e); } } private void BeginListen(IPHost[] iPHosts) { int threadCount = Config.GetValue(TouchSocketConfigExtension.ThreadCountProperty); if (threadCount > 0) { while (!ThreadPool.SetMinThreads(threadCount, threadCount)) { if (--threadCount <= 10) { break; } } } List networkMonitors = new List(); foreach (var iPHost in iPHosts) { Socket socket = new Socket(iPHost.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { ReceiveBufferSize = BufferLength, SendBufferSize = BufferLength }; if (m_config.GetValue(TouchSocketConfigExtension.ReuseAddressProperty)) { socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } PreviewBind(socket); socket.Bind(iPHost.EndPoint); socket.Listen(m_backlog); networkMonitors.Add(new NetworkMonitor(iPHost, socket)); } m_monitors = networkMonitors.ToArray(); foreach (var networkMonitor in m_monitors) { SocketAsyncEventArgs e = new SocketAsyncEventArgs { UserToken = networkMonitor.Socket }; e.Completed += Args_Completed; if (!networkMonitor.Socket.AcceptAsync(e)) { OnAccepted(e); } } } private void OnAccepted(SocketAsyncEventArgs e) { if (!DisposedValue) { if (e.SocketError == SocketError.Success && e.AcceptSocket != null) { Socket socket = e.AcceptSocket; socket.ReceiveBufferSize = BufferLength; socket.SendBufferSize = BufferLength; if (SocketClients.Count < m_maxCount) { SocketInit(socket); } else { socket.SafeDispose(); Logger.Warning(this, "连接客户端数量已达到设定最大值"); } } e.AcceptSocket = null; try { if (!((Socket)e.UserToken).AcceptAsync(e)) { OnAccepted(e); } } catch { e.Dispose(); return; } } } private void SetClientConfiguration(SocketClient client) { client.m_usePlugin = m_usePlugin; client.Config = m_config; client.m_service = this; client.Logger = Container.Resolve(); client.m_receiveType = m_receiveType; client.BufferLength = BufferLength; if (client.CanSetDataHandlingAdapter) { client.SetDataHandlingAdapter(Config.GetValue(TouchSocketConfigExtension.DataHandlingAdapterProperty).Invoke()); } } private void SocketInit(Socket socket) { try { if (Config.GetValue(TouchSocketConfigExtension.NoDelayProperty)) { socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } TClient client = GetClientInstence(); SetClientConfiguration(client); client.SetSocket(socket); client.InternalInitialized(); OperationEventArgs args = new OperationEventArgs { ID = GetDefaultNewID() }; client.InternalConnecting(args);//Connecting if (args.IsPermitOperation) { client.m_id = args.ID; if (SocketClients.TryAdd(client)) { client.InternalConnected(new MsgEventArgs("客户端成功连接")); if (!client.MainSocket.Connected) { return; } if (m_useSsl) { try { client.BeginReceiveSsl(m_receiveType, (ServiceSslOption)m_config.GetValue(TouchSocketConfigExtension.SslOptionProperty)); } catch (System.Exception ex) { OnAuthenticatingError(ex); return; } } else { client.BeginReceive(m_receiveType); } } else { throw new Exception($"ID={client.m_id}重复"); } } else { socket.SafeDispose(); } } catch (Exception ex) { socket.SafeDispose(); Logger.Log(LogType.Error, this, "接收新连接错误", ex); } } } /// /// TCP服务器 /// public class TcpService : TcpService { /// /// 处理数据 /// public ReceivedEventHandler Received { get; set; } /// /// /// /// /// /// protected override void OnReceived(SocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) { Received?.Invoke(socketClient, byteBlock, requestInfo); base.OnReceived(socketClient, byteBlock, requestInfo); } } }