using Serein.Library.Api; using Serein.Library.Utils; using Serein.Proto.WebSocket.Handle; namespace Serein.Proto.WebSocket { /// /// 消息处理上下文 /// public class WebSocketHandleContext { /// /// 构造函数,传入发送消息的异步方法 /// /// public WebSocketHandleContext(Func sendAsync) { _sendAsync = sendAsync; } /// /// 重置上下文 /// public void Reset() { MsgRequest = null; MsgData = null; ErrorMessage = null; Model = null; IsError = false; } /// /// 标记是否已经处理,如果是,则提前退出 /// public bool Handle { get; set; } /// /// WebSocket 模块配置 /// public ModuleConfig Model { get; set; } /// /// 消息本体(IJsonToken) /// public IJsonToken? MsgRequest { get; set; } /// /// 此次消息的数据 /// public IJsonToken? MsgData { get; set; } /// /// 是否发生错误 /// public bool IsError { get; set; } /// /// 错误消息 /// public string ErrorMessage { get; set; } /// /// 用于在同一个 Web Socket 中调用上下文中, 共享某个对象 /// private object? _wsTag; private object _wsTagLockObj = new object(); /// /// 设置共享对象,不建议设置非托管对象 /// /// /// public void SetTag(T tag) { lock (_wsTagLockObj) { _wsTag = tag; } } /// /// 获取共享对象(将在同一个 Web Socket 调起的上下文中保持一致) /// /// /// public object? GetTag() { TryGetTag(out object? tag); return tag; } /// /// 获取共享对象(将在同一个 Web Socket 调起的上下文中保持一致) /// /// /// public T? GetTag() { TryGetTag(out T? tag); return tag; } /// /// 获取共享对象(将在同一个 Web Socket 调起的上下文中保持一致) /// /// /// //public bool TryGetTag([NotNullWhen(true)] out T? tag) public bool TryGetTag(out T? tag) { lock (_wsTagLockObj) { if (_wsTag is T t) { tag = t; return true; } tag = default; return false; } } /// /// 异常外部感知使能 /// public Action? OnExceptionTracking { get; set; } /// /// 处理回复消息的函数 /// public Func OnReplyMakeData { get; set; } /// /// 获取回复内容的回调 /// public Action? OnReply { get; set; } /// /// 发送消息 /// private Func _sendAsync; /// /// 发送消息 /// /// /// public async Task SendAsync(string msg) { await _sendAsync.Invoke(msg); } /// /// 触发异常追踪 /// public void TriggerExceptionTracking(string exMessage) { var ex = new SereinWebSocketHandleException(exMessage); TriggerExceptionTracking(ex); } /// /// 触发异常追踪 /// public void TriggerExceptionTracking(Exception ex) { IsError = true; var msgId = Model.MsgId; var theme = Model.Theme; ErrorMessage = $"请求[{msgId}]主题[{theme}]异常 :{ex.Message}"; OnExceptionTracking?.Invoke(ex); var error = OnReplyMakeData?.Invoke(this, ex.Message); // 触发回复消息 _ = SendAsync(JsonHelper.Serialize(error)).ContinueWith((t) => { if (t.IsFaulted) { Console.WriteLine($"发送错误消息失败: {t.Exception?.Message}"); } }); // 发送错误消息 } } }