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服务器 /// 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 var fullUrl = (ssl ? "wss://" : "ws://") + url; // 创建WebSocket实例 _webSocket = new WebSocket(fullUrl); _webSocket.EnableAutoSendPing = false; // 绑定事件处理器 _webSocket.Opened += OnSocketOpened!; _webSocket.Closed += OnSocketClosed!; _webSocket.MessageReceived += OnSocketMessageReceived!; _webSocket.Error += OnSocketError!; // 打开连接 _webSocket.Open(); } catch (Exception ex) { _logger.LogError(ex, $"[{_clientName}] 连接异常: {ex.Message}"); ConnectionError?.Invoke(this, $"无法连接到 {url}: {ex.Message}"); throw; } } /// /// 断开WebSocket连接 /// public void Disconnect() { ThrowIfDisposed(); try { _logger.LogInformation($"[{_clientName}] 断开连接"); // 停止消息发送定时器 StopMessageDeferTimer(); // 清空消息队列 ClearMessageQueue(); // 关闭WebSocket连接 if (_webSocket != null) { _webSocket.Close(); _webSocket = null; } } catch (Exception ex) { _logger.LogError(ex, $"[{_clientName}] 断开连接异常: {ex.Message}"); } } /// /// 发送消息 /// 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 var messageId = _messageIdManager.GenerateGeneralMessageId(message, callback, errorHandler); // 添加到消息队列 _messageFifo.Add(message); // 启动消息发送定时器 StartMessageDeferTimer(); _logger.LogDebug($"[{_clientName}] 消息已加入队列: message_id={messageId}"); return messageId; } /// /// 发送日志获取消息 /// 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 var messageId = _messageIdManager.GenerateLogGetMessageId(message, callback); // 将消息加入队列并启动定时器 _messageFifo.Add(message); StartMessageDeferTimer(); _logger.LogDebug($"[{_clientName}] 日志获取消息已加入队列: message_id={messageId}"); return messageId; } /// /// 处理接收到的消息 /// 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; } // 处理特定消息类型 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; } } /// /// 设置消息处理器 /// public void SetMessageHandler(string[] names, MessageHandler handler) { ThrowIfDisposed(); _messageIdManager.SetMessageHandler(names, handler); } /// /// 取消设置消息处理器 /// public void UnsetMessageHandler(string[] names) { ThrowIfDisposed(); _messageIdManager.UnsetMessageHandler(names); } /// /// 检查是否为当前日志获取消息 /// public bool IsCurrentLogGetMessage(long messageId) { ThrowIfDisposed(); return _messageIdManager.IsCurrentLogGetMessage(messageId); } /// /// 重置日志获取ID /// public void ResetLogGetId() { ThrowIfDisposed(); _messageIdManager.ResetLogGetId(); } /// /// 清理过期的消息处理器 /// public void CleanupExpiredHandlers(int maxAge = 30000) { ThrowIfDisposed(); _messageIdManager.CleanupExpiredHandlers(maxAge); } #endregion } }