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