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