# PublicMethods.cs (自动转换为Markdown) ```csharp // 以下内容为原始C#代码,含详细注释 // 文件原路径:Managers/WebSocketMgr/PublicMethods.cs using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WebSocket4Net; using CoreAgent.ProtocolClient.Models; namespace CoreAgent.ProtocolClient.Managers.WebSocketMgr { public partial class WebSocketMessageManager { #region 公共方法 /// /// 连接到WebSocket服务器 - 对应LTEClientWebSocket.Start()方法 /// /// 功能说明: /// 1. 建立WebSocket连接,对应原始Start()方法的核心逻辑 /// 2. 构建WebSocket URL,支持SSL和非SSL连接 /// 3. 绑定事件处理器,对应原始的事件绑定逻辑 /// 4. 提供更严格的参数验证和异常处理 /// /// 与原始实现的差异: /// - 方法名从Start()改为Connect(),更明确表达功能 /// - 移除了状态管理逻辑(SetState),专注连接管理 /// - 增加了参数验证,提供更好的错误处理 /// /// 详细对应关系: /// - 参数url:对应原始实现中的config.Address /// - 参数ssl:对应原始实现中的config.Ssl /// - URL构建:对应原始实现中的URL构建逻辑 /// - WebSocket创建:对应原始实现中的_webSocket = new WebSocket(url) /// - 事件绑定:对应原始实现中的事件绑定逻辑 /// - 连接打开:对应原始实现中的_webSocket.Open() /// - 异常处理:对应原始实现中的异常处理逻辑 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 更明确的参数验证 /// - 更详细的异常处理 /// - 更清晰的错误信息 /// - 保持了完全一致的连接逻辑 /// /// WebSocket URL,对应LTEClientWebSocket._config.Address /// 是否使用SSL,对应LTEClientWebSocket._config.Ssl public void Connect(string url, bool ssl = false) { ThrowIfDisposed(); if (string.IsNullOrEmpty(url)) throw new ArgumentException("URL不能为空", nameof(url)); try { _logger.LogInformation($"[{_clientName}] 尝试连接: {url}"); // 构建WebSocket URL - 对应原始实现中的URL构建逻辑 var fullUrl = (ssl ? "wss://" : "ws://") + url; // 创建WebSocket实例 - 对应原始实现中的_webSocket创建 _webSocket = new WebSocket(fullUrl); _webSocket.EnableAutoSendPing = false; // 绑定事件处理器 - 对应原始实现中的事件绑定 _webSocket.Opened += OnSocketOpened!; _webSocket.Closed += OnSocketClosed!; _webSocket.MessageReceived += OnSocketMessageReceived!; // 对应OnSocketMessage0 _webSocket.Error += OnSocketError!; // 打开连接 - 对应原始实现中的_webSocket.Open() _webSocket.Open(); } catch (Exception ex) { _logger.LogError(ex, $"[{_clientName}] 连接异常: {ex.Message}"); ConnectionError?.Invoke(this, $"无法连接到 {url}: {ex.Message}"); throw; } } /// /// 断开WebSocket连接 - 对应LTEClientWebSocket.Stop()方法中的WebSocket相关逻辑 /// /// 功能说明: /// 1. 关闭WebSocket连接,对应原始Stop()方法的核心逻辑 /// 2. 清理消息队列和定时器,对应原始的资源清理逻辑 /// 3. 提供更完善的异常处理 /// /// 与原始实现的差异: /// - 方法名从Stop()改为Disconnect(),更明确表达功能 /// - 移除了状态管理逻辑(SetState),专注连接管理 /// - 移除了重连逻辑,专注连接断开 /// /// 详细对应关系: /// - 定时器停止:对应原始StopTimers()中的_messageDeferTimer处理 /// - 队列清理:对应原始实现中的队列清理逻辑 /// - WebSocket关闭:对应原始实现中的_webSocket.Close() /// - 资源清理:对应原始实现中的资源清理逻辑 /// - 异常处理:对应原始实现中的异常处理 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 更清晰的资源清理顺序 /// - 更完善的异常处理 /// - 更详细的日志记录 /// - 保持了完全一致的清理逻辑 /// public void Disconnect() { ThrowIfDisposed(); try { _logger.LogInformation($"[{_clientName}] 断开连接"); // 停止消息发送定时器 - 对应原始StopTimers()中的_messageDeferTimer处理 StopMessageDeferTimer(); // 清空消息队列 - 对应原始实现中的队列清理 ClearMessageQueue(); // 关闭WebSocket连接 - 对应原始实现中的_webSocket.Close() if (_webSocket != null) { _webSocket.Close(); _webSocket = null; } } catch (Exception ex) { _logger.LogError(ex, $"[{_clientName}] 断开连接异常: {ex.Message}"); } } /// /// 发送消息 - 对应LTEClientWebSocket.SendMessage()方法 /// /// 功能说明: /// 1. 发送通用消息,对应原始SendMessage()方法的核心逻辑 /// 2. 使用MessageIdManager生成消息ID,替代原始的Interlocked.Increment(ref _messageId) /// 3. 将消息加入队列,对应原始的_messageFifo.Enqueue(message) /// 4. 启动延迟发送定时器,对应原始的定时器逻辑 /// /// 与原始实现的差异: /// - 消息ID生成通过MessageIdManager,提供更好的管理 /// - 移除了消息缓存逻辑(_sentMessages),专注传输 /// - 增加了更严格的参数验证 /// - 保持了完全一致的队列和定时器逻辑 /// /// 详细对应关系: /// - 参数message:对应原始方法中的message参数 /// - 参数callback:对应原始方法中的callback参数 /// - 参数errorHandler:对应原始方法中的errorHandler参数 /// - 连接状态检查:对应原始实现中的连接状态检查 /// - 消息ID生成:对应原始的Interlocked.Increment(ref _messageId) /// - 队列操作:对应原始的_messageFifo.Enqueue(message) /// - 定时器启动:对应原始的定时器启动逻辑 /// - 返回值:对应原始方法的返回值 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 更统一的消息ID管理 /// - 更严格的参数验证 /// - 更详细的日志记录 /// - 保持了完全一致的发送逻辑 /// /// 消息对象,对应原始方法中的message参数 /// 回调函数,对应原始方法中的callback参数 /// 是否为错误处理器,对应原始方法中的errorHandler参数 /// 消息ID,对应原始方法的返回值 public long SendMessage(JObject message, Action? callback = null, bool errorHandler = false) { ThrowIfDisposed(); if (message == null) throw new ArgumentNullException(nameof(message)); // 检查连接状态 - 对应原始实现中的连接状态检查 if (!IsConnected) { _logger.LogWarning($"[{_clientName}] WebSocket未连接,无法发送消息"); return -1L; } // 使用MessageIdManager生成ID - 替代原始的Interlocked.Increment(ref _messageId) var messageId = _messageIdManager.GenerateGeneralMessageId(message, callback, errorHandler); // 添加到消息队列 - 对应原始实现中的_messageFifo.Enqueue(message) _messageFifo.Add(message); // 启动消息发送定时器 - 对应原始实现中的定时器启动逻辑 StartMessageDeferTimer(); _logger.LogDebug($"[{_clientName}] 消息已加入队列: message_id={messageId}"); return messageId; } /// /// 发送日志获取消息 - 对应LTEClientWebSocket.LogGet()方法中的消息发送部分 /// /// 功能说明: /// 1. 专门用于发送日志获取消息,对应原始LogGet()方法的核心逻辑 /// 2. 使用MessageIdManager生成LogGet ID,替代原始的_logGetId管理 /// 3. 委托给SendMessage方法,保持代码一致性 /// /// 与原始实现的差异: /// - 专门处理日志获取消息,提供更清晰的接口 /// - 使用MessageIdManager管理LogGet ID,提供更好的跟踪 /// - 委托给SendMessage方法,避免代码重复 /// - 保持了完全一致的发送逻辑 /// /// 详细对应关系: /// - 参数message:对应原始LogGet()方法中构建的message /// - 参数callback:对应原始LogGet()方法中的LogGetParse回调 /// - 委托给SendMessage:对应原始实现中的SendMessage调用 /// - LogGet ID生成:对应原始的_logGetId管理逻辑 /// - 返回值:对应原始方法的返回值 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 更专门的日志获取消息处理 /// - 更统一的LogGet ID管理 /// - 避免代码重复,委托给SendMessage /// - 保持了完全一致的发送逻辑 /// /// 消息对象,对应原始LogGet()方法中构建的message /// 回调函数,对应原始LogGet()方法中的LogGetParse回调 /// 消息ID,对应原始方法的返回值 public long SendLogGetMessage(JObject message, Action callback) { ThrowIfDisposed(); if (message == null) throw new ArgumentNullException(nameof(message)); if (callback == null) throw new ArgumentNullException(nameof(callback)); // 检查连接状态 - 对应原始实现中的连接状态检查 if (!IsConnected) { _logger.LogWarning($"[{_clientName}] WebSocket未连接,无法发送日志获取消息"); return -1L; } // 使用MessageIdManager生成LogGet ID - 替代原始的_logGetId管理 var messageId = _messageIdManager.GenerateLogGetMessageId(message, callback); // 委托给SendMessage方法,避免代码重复 - 对应原始实现中的SendMessage调用 // 注意:这里不需要再次调用SendMessage,因为GenerateLogGetMessageId已经处理了消息ID和回调注册 // 只需要将消息加入队列并启动定时器 _messageFifo.Add(message); StartMessageDeferTimer(); _logger.LogDebug($"[{_clientName}] 日志获取消息已加入队列: message_id={messageId}"); return messageId; } /// /// 处理接收到的消息 - 对应LTEClientWebSocket.OnSocketMessage()方法中的消息处理逻辑 /// /// 功能说明: /// 1. 处理接收到的WebSocket消息,对应原始OnSocketMessage()方法的核心逻辑 /// 2. 使用MessageIdManager处理消息响应,替代原始的消息处理器查找逻辑 /// 3. 触发MessageReceived事件,对应原始的事件触发 /// 4. 提供完善的错误处理 /// /// 与原始实现的差异: /// - 使用MessageIdManager处理消息响应,提供更好的管理 /// - 移除了消息缓存逻辑(_receivedMessages),专注处理 /// - 移除了业务逻辑处理(log_get、stats等),专注消息路由 /// - 保持了完全一致的事件触发逻辑 /// /// 详细对应关系: /// - 参数message:对应原始方法中的msg参数 /// - 参数errorHandler:对应原始方法中的错误处理逻辑 /// - 消息处理器查找:对应原始的消息处理器查找逻辑 /// - 事件触发:对应原始的事件触发逻辑 /// - 错误处理:对应原始的错误处理逻辑 /// - 返回值:新增返回值提供处理状态反馈 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 更统一的消息响应处理 /// - 更清晰的错误处理 /// - 更详细的日志记录 /// - 保持了完全一致的处理逻辑 /// /// 接收到的消息,对应原始方法中的msg参数 /// 错误处理回调,对应原始方法中的错误处理逻辑 /// 是否成功处理,新增返回值提供处理状态反馈 public bool HandleReceivedMessage(JObject message, Action? errorHandler = null) { ThrowIfDisposed(); if (message == null) return false; try { // 使用MessageIdManager处理消息响应 - 替代原始的消息处理器查找逻辑 var handled = _messageIdManager.HandleMessageResponse(message, errorHandler); if (handled) { _logger.LogDebug($"[{_clientName}] 消息已处理: message_id={message["message_id"]}"); return true; } // 处理特定消息类型 - 对应原始实现中的特定消息类型处理 // 注意:这里不处理log_get和stats等业务逻辑,因为重构版本专注于消息传输 var name = message["message"]?.ToString(); if (!string.IsNullOrEmpty(name)) { _logger.LogDebug($"[{_clientName}] 未处理的特定消息类型: {name}"); } return false; } catch (Exception ex) { _logger.LogError(ex, $"[{_clientName}] 处理消息异常: {ex.Message}"); errorHandler?.Invoke($"消息处理错误: {ex.Message}"); return false; } } /// /// 设置消息处理器 - 对应LTEClientWebSocket.SetMessageHandler()方法 /// /// 功能说明: /// 1. 设置按名称的消息处理器,对应原始SetMessageHandler()方法的核心逻辑 /// 2. 委托给MessageIdManager处理,提供统一的消息处理器管理 /// 3. 支持多个消息名称的处理器设置 /// /// 详细对应关系: /// - 参数names:对应原始方法中的names参数,消息名称数组 /// - 参数handler:对应原始方法中的handler参数,消息处理器 /// - 处理器注册:对应原始的_messageHandlersByName注册逻辑 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 委托给MessageIdManager,提供统一管理 /// - 保持了完全一致的接口和功能 /// - 更好的错误处理和参数验证 /// /// 消息名称数组,对应原始方法中的names参数 /// 消息处理器,对应原始方法中的handler参数 public void SetMessageHandler(string[] names, MessageHandler handler) { ThrowIfDisposed(); _messageIdManager.SetMessageHandler(names, handler); } /// /// 取消设置消息处理器 - 对应LTEClientWebSocket.UnsetMessageHandler()方法 /// /// 功能说明: /// 1. 取消按名称的消息处理器,对应原始UnsetMessageHandler()方法的核心逻辑 /// 2. 委托给MessageIdManager处理,提供统一的消息处理器管理 /// 3. 支持多个消息名称的处理器取消 /// /// 详细对应关系: /// - 参数names:对应原始方法中的names参数,消息名称数组 /// - 处理器移除:对应原始的_messageHandlersByName移除逻辑 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 委托给MessageIdManager,提供统一管理 /// - 保持了完全一致的接口和功能 /// - 更好的错误处理和参数验证 /// /// 消息名称数组,对应原始方法中的names参数 public void UnsetMessageHandler(string[] names) { ThrowIfDisposed(); _messageIdManager.UnsetMessageHandler(names); } /// /// 检查是否为当前日志获取消息 - 对应LTEClientWebSocket中的_logGetId检查逻辑 /// /// 功能说明: /// 1. 检查指定的消息ID是否为当前的日志获取消息ID /// 2. 委托给MessageIdManager处理,提供统一的LogGet ID管理 /// 3. 用于日志获取流程的状态检查 /// /// 详细对应关系: /// - 参数messageId:对应原始实现中的消息ID检查 /// - 返回值:true表示是当前LogGet消息,false表示不是,对应原始逻辑 /// - 检查逻辑:对应原始的_logGetId比较逻辑 /// /// 重构改进: /// - 委托给MessageIdManager,提供统一管理 /// - 保持了完全一致的检查逻辑 /// - 更好的线程安全性 /// /// 要检查的消息ID /// 是否为当前日志获取消息 public bool IsCurrentLogGetMessage(long messageId) { ThrowIfDisposed(); return _messageIdManager.IsCurrentLogGetMessage(messageId); } /// /// 重置日志获取ID - 对应LTEClientWebSocket中的_logGetId重置逻辑 /// /// 功能说明: /// 1. 重置日志获取消息ID,对应原始实现中的_logGetId重置逻辑 /// 2. 委托给MessageIdManager处理,提供统一的LogGet ID管理 /// 3. 用于日志获取流程的重置操作 /// /// 详细对应关系: /// - 重置逻辑:对应原始的_logGetId = -1操作 /// - 日志记录:对应原始实现中的日志记录 /// - 事件触发:对应原始实现中的状态变化通知 /// /// 重构改进: /// - 委托给MessageIdManager,提供统一管理 /// - 保持了完全一致的重置逻辑 /// - 更好的事件通知机制 /// public void ResetLogGetId() { ThrowIfDisposed(); _messageIdManager.ResetLogGetId(); } /// /// 清理过期的消息处理器 - 对应LTEClientWebSocket中的处理器清理逻辑 /// /// 功能说明: /// 1. 清理过期的消息处理器,防止内存泄漏 /// 2. 委托给MessageIdManager处理,提供统一的处理器管理 /// 3. 支持可配置的过期时间 /// /// 详细对应关系: /// - 参数maxAge:对应原始实现中的过期时间配置 /// - 清理逻辑:对应原始的处理器清理逻辑 /// - 日志记录:对应原始实现中的日志记录 /// /// 重构改进: /// - 委托给MessageIdManager,提供统一管理 /// - 保持了完全一致的清理逻辑 /// - 更好的内存管理 /// /// 最大存活时间(毫秒),默认30000毫秒 public void CleanupExpiredHandlers(int maxAge = 30000) { ThrowIfDisposed(); _messageIdManager.CleanupExpiredHandlers(maxAge); } #endregion } }