using System.Net.WebSockets; using XFEExtension.NetCore.CyberComm; using XFEExtension.NetCore.DelegateExtension; namespace XFEExtension.NetCore.XFEConsole; /// /// XFE控制台终端服务器 /// public class XFEConsoleTerminalServer { /// /// 服务器 /// public CyberCommServer Server { get; set; } /// /// 密码 /// public string Password { get; set; } /// /// Socket客户端-客户端信息字典 /// public Dictionary ClientInfoDictionary { get; set; } = []; /// /// 客户端连接事件 /// public event XFEEventHandler? Connected; /// /// 客户端断开连接事件 /// public event XFEEventHandler? Disconnected; /// /// 接收到客户端消息触发 /// public event XFEEventHandler? MessageReceived; /// /// 发生错误 /// public event XFEEventHandler? ErrorOccurred; /// /// 服务器启动事件 /// public event XFEEventHandler? ServerStarted; /// /// XFE控制台终端服务器 /// /// 端口号 /// 是否只在本地开启 /// 密码(默认为空) public XFEConsoleTerminalServer(int port, bool localOnly = true, string password = "") { Password = password; Server = localOnly ? new CyberCommServer($"http://localhost:{port}/") : new CyberCommServer(port); ConfigureServer(); } /// /// XFE控制台终端服务器 /// /// IP地址 /// 密码(默认为空) public XFEConsoleTerminalServer(string[] ipAddress, string password = "") { Password = password; Server = new CyberCommServer(ipAddress); ConfigureServer(); } private void ConfigureServer() { Server.StartedHandler = cancellationToken => { Server_ServerStarted(); return ValueTask.CompletedTask; }; Server.WebSocketConnectedHandler = async (eventArgs, cancellationToken) => await Server_ClientConnected(eventArgs).ConfigureAwait(false); Server.WebSocketClosedHandler = (eventArgs, cancellationToken) => { Server_ConnectionClosed(eventArgs); return ValueTask.CompletedTask; }; Server.WebSocketMessageHandler = (eventArgs, cancellationToken) => { Server_MessageReceived(eventArgs); return ValueTask.CompletedTask; }; } private void Server_MessageReceived(CyberCommServerEventArgs e) { XFEConsoleClientInfo? clientInfo; lock (ClientInfoDictionary) ClientInfoDictionary.TryGetValue(e.CurrentWebSocket, out clientInfo); if (clientInfo is null) return; switch (e.MessageType) { case BackMessageType.Text: MessageReceived?.Invoke(clientInfo, e.TextMessage!); break; case BackMessageType.Binary: break; case BackMessageType.Error: ErrorOccurred?.Invoke(clientInfo, e.Exception!); break; } } private void Server_ConnectionClosed(CyberCommServerEventArgs e) { XFEConsoleClientInfo? clientInfo; lock (ClientInfoDictionary) { if (!ClientInfoDictionary.Remove(e.CurrentWebSocket, out clientInfo)) return; } Disconnected?.Invoke(this, clientInfo); } private async Task Server_ClientConnected(CyberCommServerEventArgs e) { try { if (e.WSHeader["ClientName"] is not null && e.WSHeader["ClientID"] is not null && e.WSHeader["Password"] is not null) { var password = e.WSHeader["Password"]!; var clientName = e.WSHeader["ClientName"]!; var clientUuid = e.WSHeader["ClientID"]!; if (password == Password) { var clientInfo = new XFEConsoleClientInfo(clientName, clientUuid, password, e); lock (ClientInfoDictionary) ClientInfoDictionary.Add(e.CurrentWebSocket, clientInfo); Connected?.Invoke(this, clientInfo); return; } } } catch { } try { await e.Close(); } catch { try { e.ForceClose(); } catch { } } } private void Server_ServerStarted() { ClientInfoDictionary = []; ServerStarted?.Invoke(this); } /// /// 启动服务器 /// /// public async Task StartServer() { await Server.StartAsync().ConfigureAwait(false); await Server.RunAsync().ConfigureAwait(false); } /// /// 启动服务器并在监听就绪后返回。 /// public Task StartAsync(CancellationToken cancellationToken = default) => Server.StartAsync(cancellationToken); /// /// 停止服务器并关闭当前连接。 /// public Task StopAsync(CancellationToken cancellationToken = default) => Server.StopAsync(cancellationToken); }