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