# WebSocketMessageManager.cs (自动转换为Markdown) ```csharp // 以下内容为原始C#代码,含详细注释 // 文件原路径:Managers/WebSocketMgr/WebSocketMessageManager.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; namespace CoreAgent.ProtocolClient.Managers.WebSocketMgr { /// /// WebSocket消息管理器 - 专门处理WebSocket的收发业务 /// /// 重构说明: /// 1. 对应LTEClientWebSocket中的WebSocket连接和消息传输功能 /// 2. 集成MessageIdManager统一管理消息ID和回调 /// 3. 移除_sentMessages和_receivedMessages消息缓存,专注传输 /// 4. 移除业务逻辑功能(统计更新、日志解析等),实现职责分离 /// /// 主要功能: /// - WebSocket连接管理(对应LTEClientWebSocket.Start()和Stop()) /// - 消息发送和接收(对应LTEClientWebSocket.SendMessage()和OnSocketMessage()) /// - 消息队列和批量发送(对应LTEClientWebSocket._messageFifo和SendMessageNow()) /// - 事件通知(对应LTEClientWebSocket的事件系统) /// /// 与LTEClientWebSocket的详细对应关系: /// /// 1. 连接管理对应关系: /// - Connect() 对应 Start() 方法中的WebSocket连接建立逻辑 /// - Disconnect() 对应 Stop() 方法中的WebSocket关闭逻辑 /// - OnSocketOpened/OnSocketClosed/OnSocketError 对应原始的事件处理器 /// /// 2. 消息发送对应关系: /// - SendMessage() 对应 SendMessage() 方法的核心逻辑 /// - SendLogGetMessage() 对应 LogGet() 方法中的消息发送部分 /// - _messageFifo 对应原始的 _messageFifo 队列 /// - SendMessageNow() 对应原始的 SendMessageNow() 方法 /// - StartMessageDeferTimer() 对应原始的定时器启动逻辑 /// /// 3. 消息接收对应关系: /// - OnSocketMessageReceived() 对应 OnSocketMessage() 方法 /// - HandleReceivedMessage() 对应 OnSocketMessage() 中的消息处理逻辑 /// - MessageReceived 事件对应原始的 MessageReceived 事件 /// /// 4. 消息ID管理对应关系: /// - MessageIdManager 替代原始的 _messageId 和 _logGetId 字段 /// - GenerateGeneralMessageId() 对应 Interlocked.Increment(ref _messageId) /// - GenerateLogGetMessageId() 对应 _logGetId 的管理逻辑 /// /// 5. 事件系统对应关系: /// - ConnectionOpened 对应原始的 ConnectionOpened 事件 /// - ConnectionClosed 对应原始的 ConnectionClosed 事件 /// - ConnectionError 对应原始的 ConnectionError 事件 /// - MessageReceived 对应原始的 MessageReceived 事件 /// - MessageSent 新增事件,提供更完整的消息生命周期通知 /// /// 6. 资源管理对应关系: /// - Dispose() 对应原始的 Dispose() 方法 /// - _disposed 字段对应原始的 _disposed 字段 /// - 定时器管理对应原始的定时器清理逻辑 /// /// 重构优势: /// 1. 职责分离:专注WebSocket传输,移除业务逻辑 /// 2. 代码复用:可在多个地方复用WebSocket管理器 /// 3. 测试友好:更容易进行单元测试 /// 4. 维护简单:更清晰的代码结构 /// 5. 功能增强:通过MessageIdManager提供更好的消息管理 /// public partial class WebSocketMessageManager : IDisposable { #region 私有字段 /// /// WebSocket实例 - 对应LTEClientWebSocket._webSocket /// 负责底层的WebSocket连接和通信 /// /// 对应关系: /// - 创建:Connect()方法中创建,对应Start()方法中的_webSocket = new WebSocket(url) /// - 配置:EnableAutoSendPing = false,对应原始实现 /// - 事件绑定:绑定Opened/Closed/MessageReceived/Error事件,对应原始事件绑定 /// - 连接:调用Open()方法,对应原始的_webSocket.Open() /// - 关闭:调用Close()方法,对应原始的_webSocket.Close() /// - 清理:在Disconnect()中设置为null,对应原始的资源清理 /// private WebSocket? _webSocket; /// /// 消息ID管理器 - 对应LTEClientWebSocket._messageId和_logGetId /// 统一管理通用消息ID和日志获取消息ID,提供更好的消息跟踪和回调管理 /// /// 对应关系: /// - _messageId 对应 MessageIdManager.GenerateGeneralMessageId() /// - _logGetId 对应 MessageIdManager.GenerateLogGetMessageId() /// - _messageHandlers 对应 MessageIdManager的内部处理器管理 /// - _messageHandlersByName 对应 MessageIdManager的按名称处理器管理 /// /// 功能增强: /// - 线程安全的ID生成,替代原始的Interlocked.Increment /// - 统一的处理器管理,提供更好的回调跟踪 /// - 自动清理过期处理器,防止内存泄漏 /// - 事件通知机制,提供ID变化通知 /// private readonly MessageIdManager _messageIdManager; /// /// 日志记录器 - 对应LTEClientWebSocket._logger /// 用于记录WebSocket操作和错误信息 /// /// 对应关系: /// - 构造函数参数:对应LTEClientWebSocket构造函数中的logger参数 /// - 日志记录:对应原始实现中的所有_logger.LogXXX调用 /// - 日志格式:保持与原始实现一致的日志格式 /// /// 功能增强: /// - 更详细的错误日志记录 /// - 更好的异常堆栈跟踪 /// - 统一的日志格式和级别 /// private readonly ILogger _logger; /// /// 客户端名称 - 对应LTEClientWebSocket._config.Name /// 用于日志记录和事件标识 /// /// 对应关系: /// - 构造函数参数:对应LTEClientWebSocket构造函数中的config.Name /// - 日志前缀:对应原始实现中所有日志的[{_config.Name}]前缀 /// - 事件标识:用于区分不同客户端的事件 /// /// 功能增强: /// - 参数验证:确保clientName不为null /// - 统一标识:在所有日志和事件中使用一致的客户端标识 /// private readonly string _clientName; /// /// 消息队列 - 对应LTEClientWebSocket._messageFifo /// 线程安全的阻塞集合,用于批量发送优化 /// 优化说明:从ConcurrentQueue改为BlockingCollection,提供更好的线程安全性和阻塞能力 /// /// 对应关系: /// - 队列类型:BlockingCollection,优化后的线程安全集合 /// - 入队操作:Add(message),对应原始的_messageFifo.Enqueue(message) /// - 出队操作:TryTake(out message),对应原始的队列处理逻辑 /// - 批量处理:支持批量消息发送,对应原始的批处理逻辑 /// /// 功能增强: /// - 线程安全:使用BlockingCollection保证线程安全 /// - 阻塞能力:支持阻塞式出队操作,提高性能 /// - 批量优化:支持批量发送减少网络开销 /// - 延迟发送:配合_messageDeferTimer实现延迟发送 /// - 资源管理:自动处理集合的完成状态 /// /// 重构改进: /// - 移除了消息缓存功能,专注传输 /// - 优化了队列操作逻辑,提供更好的性能 /// - 增强了线程安全性和资源管理 /// private readonly BlockingCollection _messageFifo; /// /// 消息延迟发送定时器 - 对应LTEClientWebSocket._messageDeferTimer /// 用于实现消息的批量发送和延迟发送机制 /// 保持与原始实现完全一致的逻辑 /// /// 对应关系: /// - 定时器类型:Timer,与原始实现完全一致 /// - 启动逻辑:StartMessageDeferTimer(),对应原始的定时器启动 /// - 停止逻辑:StopMessageDeferTimer(),对应原始的定时器停止 /// - 延迟策略:1毫秒延迟,与原始实现完全一致 /// - 批处理大小:100条消息,与原始实现完全一致 /// /// 功能保持: /// - 批量发送:当队列中消息少于100条时,延迟1毫秒发送 /// - 立即发送:当队列中消息达到100条时,立即发送 /// - 资源管理:在Disconnect()和Dispose()中正确释放 /// /// 重构改进: /// - 更清晰的定时器管理逻辑 /// - 更好的异常处理 /// - 保持了完全一致的批处理策略 /// private Timer? _messageDeferTimer; /// /// 释放标志 - 对应LTEClientWebSocket._disposed /// 防止重复释放和已释放对象的操作 /// /// 对应关系: /// - 字段类型:bool,对应原始的_disposed字段 /// - 返回值:true表示已释放,false表示未释放,对应原始实现 /// - 使用场景:外部检查对象释放状态,对应原始实现 /// - 线程安全:直接返回_disposed字段值,对应原始实现 /// /// 功能保持: /// - 释放状态检查:外部可以检查对象是否已释放 /// - 资源保护:防止对已释放对象的操作 /// - 状态查询:提供对象状态的查询接口 /// /// 重构改进: /// - 保持了完全一致的检查逻辑 /// - 保持了完全一致的返回值语义 /// - 保持了完全一致的使用场景 /// private bool _disposed; /// /// 同步锁对象 /// 用于确保线程安全的操作 /// /// 对应关系: /// - 新增功能:原始实现中没有显式的同步锁 /// - 用途:确保关键操作的线程安全 /// - 使用场景:在需要线程安全的地方使用lock语句 /// /// 功能增强: /// - 线程安全:确保关键操作的原子性 /// - 死锁预防:使用细粒度锁避免死锁 /// - 性能优化:最小化锁的持有时间 /// private readonly object _lockObject = new object(); #endregion #region 事件 /// /// 连接打开事件 - 对应LTEClientWebSocket.ConnectionOpened /// 当WebSocket连接成功建立时触发 /// /// 对应关系: /// - 事件类型:EventHandler,与原始实现完全一致 /// - 触发时机:在OnSocketOpened()中触发,对应原始的OnSocketOpened事件处理 /// - 触发条件:WebSocket连接成功建立时 /// - 事件参数:无参数,与原始实现完全一致 /// /// 功能保持: /// - 连接状态通知:通知外部连接已建立 /// - 事件订阅:支持多个订阅者 /// - 异步触发:事件触发不会阻塞WebSocket操作 /// /// 重构改进: /// - 更清晰的触发时机 /// - 更好的错误处理 /// - 保持了完全一致的事件接口 /// public event EventHandler? ConnectionOpened; /// /// 连接关闭事件 - 对应LTEClientWebSocket.ConnectionClosed /// 当WebSocket连接关闭时触发 /// /// 对应关系: /// - 事件类型:EventHandler,与原始实现完全一致 /// - 触发时机:在OnSocketClosed()中触发,对应原始的OnSocketClosed事件处理 /// - 触发条件:WebSocket连接关闭时 /// - 事件参数:无参数,与原始实现完全一致 /// /// 功能保持: /// - 连接状态通知:通知外部连接已关闭 /// - 事件订阅:支持多个订阅者 /// - 异步触发:事件触发不会阻塞WebSocket操作 /// /// 重构改进: /// - 更清晰的触发时机 /// - 更好的资源清理 /// - 保持了完全一致的事件接口 /// public event EventHandler? ConnectionClosed; /// /// 连接错误事件 - 对应LTEClientWebSocket.ConnectionError /// 当WebSocket连接发生错误时触发 /// /// 对应关系: /// - 事件类型:EventHandler,与原始实现完全一致 /// - 触发时机:在OnSocketError()和异常处理中触发,对应原始的错误处理 /// - 触发条件:WebSocket连接错误、消息处理错误等 /// - 事件参数:错误信息字符串,与原始实现完全一致 /// /// 功能保持: /// - 错误通知:通知外部连接或处理错误 /// - 事件订阅:支持多个订阅者 /// - 异步触发:事件触发不会阻塞WebSocket操作 /// /// 重构改进: /// - 更详细的错误信息 /// - 更好的异常处理 /// - 保持了完全一致的事件接口 /// public event EventHandler? ConnectionError; /// /// 消息接收事件 - 对应LTEClientWebSocket.MessageReceived /// 当接收到WebSocket消息时触发 /// /// 对应关系: /// - 事件类型:EventHandler,与原始实现完全一致 /// - 触发时机:在OnSocketMessageReceived()中触发,对应原始的OnSocketMessage事件处理 /// - 触发条件:接收到WebSocket消息并解析成功后 /// - 事件参数:解析后的JObject消息,与原始实现完全一致 /// /// 功能保持: /// - 消息通知:通知外部接收到新消息 /// - 事件订阅:支持多个订阅者 /// - 异步触发:事件触发不会阻塞消息处理 /// - 触发顺序:在消息处理开始时就触发,与原始实现完全一致 /// /// 重构改进: /// - 更清晰的触发时机 /// - 更好的消息解析 /// - 保持了完全一致的事件接口和触发顺序 /// public event EventHandler? MessageReceived; /// /// 消息发送事件 - 新增功能,LTEClientWebSocket中没有对应事件 /// 当消息成功发送时触发,提供更完整的消息生命周期通知 /// /// 对应关系: /// - 事件类型:EventHandler,与MessageReceived保持一致 /// - 触发时机:在SendMessageNow()中触发,对应消息发送成功时 /// - 触发条件:消息成功发送到WebSocket时 /// - 事件参数:发送的JObject消息,与MessageReceived保持一致 /// /// 功能增强: /// - 消息生命周期:提供完整的消息发送通知 /// - 调试支持:便于调试消息发送流程 /// - 监控支持:便于监控消息发送状态 /// - 事件订阅:支持多个订阅者 /// /// 重构优势: /// - 更完整的消息生命周期管理 /// - 更好的调试和监控支持 /// - 与MessageReceived事件形成对称的事件系统 /// public event EventHandler? MessageSent; #endregion #region 属性 /// /// 是否已连接 - 对应LTEClientWebSocket.IsConnected /// 检查WebSocket连接状态 /// /// 对应关系: /// - 属性类型:bool,与原始实现完全一致 /// - 检查逻辑:_webSocket?.State == WebSocketState.Open,与原始实现完全一致 /// - 使用场景:在SendMessage()中检查连接状态,对应原始实现 /// - 返回值:true表示已连接,false表示未连接,与原始实现完全一致 /// /// 功能保持: /// - 连接状态检查:快速检查WebSocket连接状态 /// - 空安全:使用?.操作符避免空引用异常 /// - 实时状态:反映WebSocket的实时连接状态 /// /// 重构改进: /// - 保持了完全一致的检查逻辑 /// - 保持了完全一致的返回值语义 /// - 保持了完全一致的使用场景 /// public bool IsConnected => _webSocket?.State == WebSocketState.Open; /// /// WebSocket状态 - 对应LTEClientWebSocket._webSocket?.State /// 获取详细的WebSocket连接状态 /// /// 对应关系: /// - 属性类型:WebSocketState,对应原始的_webSocket?.State /// - 返回值:WebSocket的详细状态,对应原始实现 /// - 空安全:使用??操作符提供默认值,对应原始实现 /// - 使用场景:提供更详细的连接状态信息 /// /// 功能保持: /// - 详细状态:提供WebSocket的详细连接状态 /// - 空安全:当_webSocket为null时返回WebSocketState.None /// - 实时状态:反映WebSocket的实时状态 /// /// 重构改进: /// - 保持了完全一致的状态获取逻辑 /// - 保持了完全一致的默认值处理 /// - 保持了完全一致的使用场景 /// public WebSocketState State => _webSocket?.State ?? WebSocketState.None; /// /// 是否已释放 - 对应LTEClientWebSocket._disposed /// 检查对象是否已被释放 /// /// 对应关系: /// - 属性类型:bool,对应原始的_disposed字段 /// - 返回值:true表示已释放,false表示未释放,对应原始实现 /// - 使用场景:外部检查对象释放状态,对应原始实现 /// - 线程安全:直接返回_disposed字段值,对应原始实现 /// /// 功能保持: /// - 释放状态检查:外部可以检查对象是否已释放 /// - 资源保护:防止对已释放对象的操作 /// - 状态查询:提供对象状态的查询接口 /// /// 重构改进: /// - 保持了完全一致的检查逻辑 /// - 保持了完全一致的返回值语义 /// - 保持了完全一致的使用场景 /// public bool IsDisposed => _disposed; /// /// 消息队列数量 - 对应LTEClientWebSocket._messageFifo.Count /// 获取当前待发送消息的数量 /// /// 对应关系: /// - 属性类型:int,对应原始的_messageFifo.Count /// - 返回值:队列中待发送消息的数量,对应原始实现 /// - 使用场景:监控消息队列状态,对应原始实现 /// - 线程安全:BlockingCollection.Count是线程安全的,对应原始实现 /// /// 功能保持: /// - 队列监控:监控当前待发送消息的数量 /// - 性能监控:便于监控消息发送性能 /// - 调试支持:便于调试消息队列状态 /// /// 重构改进: /// - 保持了完全一致的计数逻辑 /// - 保持了完全一致的返回值语义 /// - 保持了完全一致的使用场景 /// - 优化:使用BlockingCollection提供更好的线程安全性 /// public int MessageQueueCount => _messageFifo.Count; /// /// 消息ID管理器 - 提供对MessageIdManager的访问 /// 允许外部访问消息ID管理功能 /// /// 对应关系: /// - 属性类型:MessageIdManager,对应原始的_messageId和_logGetId管理 /// - 返回值:内部的消息ID管理器实例,对应原始实现 /// - 使用场景:外部访问消息ID管理功能,对应原始实现 /// - 封装性:提供对内部MessageIdManager的访问,对应原始实现 /// /// 功能保持: /// - 功能访问:外部可以访问消息ID管理功能 /// - 封装性:保持内部实现的封装性 /// - 扩展性:支持外部扩展消息ID管理功能 /// /// 重构改进: /// - 更统一的消息ID管理接口 /// - 更好的功能封装 /// - 保持了完全一致的功能访问方式 /// public MessageIdManager MessageIdManager => _messageIdManager; #endregion } }