using System.Net.WebSockets; using System.Text; using XFEExtension.NetCore.Exceptions; namespace XFEExtension.NetCore.CyberComm; /// /// CyberComm客户端事件参数 /// /// 消息类型 /// 当前WebSocket /// 文本消息 /// 异常消息(如果有的话) /// 二进制消息 /// 是否发送完成 public abstract record CyberCommClientEventArgs(BackMessageType MessageType, ClientWebSocket CurrentWebSocket, string? TextMessage, XFECyberCommException? Exception, byte[]? BinaryMessage, bool EndOfMessage) { private Func, WebSocketMessageType, CancellationToken, ValueTask>? SendHandler { get; init; } private Func>? CloseHandler { get; init; } /// /// 发送文本消息 /// /// 待发送的文本 /// /// 发送进程 public async Task ReplyMessage(string message) { try { var sendBuffer = Encoding.UTF8.GetBytes(message); if (SendHandler is not null) { var result = await SendHandler(sendBuffer, WebSocketMessageType.Text, CancellationToken.None).ConfigureAwait(false); if (!result.IsSuccess) throw result.Exception ?? new InvalidOperationException($"发送失败:{result.Status}"); } else await CurrentWebSocket.SendAsync(new ArraySegment(sendBuffer), WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception ex) { throw new XFECyberCommException("收到服务器端数据后客户端回复文本数据时出现异常", ex); } } /// /// 关闭连接 /// /// public async Task Close() { try { if (CloseHandler is not null) await CloseHandler(WebSocketCloseStatus.NormalClosure, "Connection Closed", CancellationToken.None).ConfigureAwait(false); else await CurrentWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection Closed", CancellationToken.None); } catch (Exception ex) { throw new XFECyberCommException("关闭客户端连接时出现异常", ex); } } internal CyberCommClientEventArgs(ClientWebSocket clientWebSocket, string message, bool endOfMessage) : this(BackMessageType.Text, clientWebSocket, message, null, null, endOfMessage) { } internal CyberCommClientEventArgs(ClientWebSocket clientWebSocket, byte[] bytes, bool endOfMessage) : this(BackMessageType.Binary, clientWebSocket, null, null, bytes, endOfMessage) { } internal CyberCommClientEventArgs(ClientWebSocket clientWebSocket, XFECyberCommException ex) : this(BackMessageType.Error, clientWebSocket, null, ex, null, true) { } internal CyberCommClientEventArgs WithTransport(CyberCommWebSocketPeer peer) => this with { SendHandler = peer.SendAsync, CloseHandler = peer.CloseAsync }; }