You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.7 KiB

using CoreAgent.Domain.Helpers;
using CoreAgent.Domain.Interfaces.CustomWSClient;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebSocket4Net;
namespace CoreAgent.Infrastructure.Services.CustomWSClient
{
public class CustomWebSocketClient : IDisposable
{
private readonly ILogger logger;
private readonly string serverUrl;
private WebSocket? webSocket;
protected readonly ICustomMessageHandler messageHandler;
private bool _disposed;
protected CustomWebSocketClient(ILogger logger, string serverUrl, ICustomMessageHandler messageHandler)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.serverUrl = $"ws://{serverUrl}";
this.messageHandler = messageHandler ?? throw new ArgumentNullException(nameof(messageHandler));
}
public void Start()
{
try
{
logger.LogInformation("正在启动WebSocket客户端,连接到服务器: {ServerUrl}", serverUrl);
webSocket = new WebSocket4Net.WebSocket(serverUrl);
ConfigureWebSocketHandlers();
webSocket.EnableAutoSendPing = false;
webSocket.Open();
logger.LogInformation("WebSocket客户端启动成功");
}
catch (Exception ex)
{
logger.LogError(ex, "WebSocket客户端启动失败: {Message}", ex.Message);
throw;
}
}
private void ConfigureWebSocketHandlers()
{
try
{
webSocket!.Opened += (s, e) => HandleOpen(e);
webSocket.Closed += (s, e) => HandleClosed(e);
webSocket.Error += (s, e) => HandleError(e);
webSocket.MessageReceived += (s, e) => HandleMessage(e);
webSocket.DataReceived += (s, e) => HandleDataReceivedMessage(e);
logger.LogDebug("WebSocket事件处理器配置完成");
}
catch (Exception ex)
{
logger.LogError(ex, "配置WebSocket事件处理器时发生错误: {Message}", ex.Message);
throw;
}
}
private void HandleOpen(EventArgs @event)
{
try
{
logger.LogInformation("WebSocket已连接到服务器: {ServerUrl}", serverUrl);
}
catch (Exception ex)
{
logger.LogError(ex, "处理WebSocket打开事件时发生错误: {Message}", ex.Message);
}
}
private void HandleClosed(EventArgs @event)
{
try
{
logger.LogInformation("WebSocket连接已关闭,状态: {State}", webSocket?.State);
}
catch (Exception ex)
{
logger.LogError(ex, "处理WebSocket关闭事件时发生错误: {Message}", ex.Message);
}
}
private void HandleError(SuperSocket.ClientEngine.ErrorEventArgs ex)
{
try
{
logger.LogError(ex.Exception, "WebSocket发生错误: {Message}", ex.Exception.Message);
}
catch (Exception e)
{
logger.LogError(e, "处理WebSocket错误事件时发生异常: {Message}", e.Message);
}
}
private void HandleMessage(MessageReceivedEventArgs e)
{
try
{
if (webSocket is { State: WebSocketState.Connecting or WebSocketState.Open })
{
logger.LogDebug("收到WebSocket消息: {Message}", e.Message);
messageHandler.HandleMessage(e.Message, new ObserverCustomWebSocketClient(webSocket, logger));
}
else
{
logger.LogWarning("收到消息时WebSocket状态异常: {State}, 消息内容: {Message}", webSocket!.State, e.Message);
}
}
catch (Exception ex)
{
logger.LogError(ex, "处理WebSocket消息时发生错误: {Message}, 原始消息: {OriginalMessage}", ex.Message, e.Message);
}
}
private void HandleDataReceivedMessage(DataReceivedEventArgs data)
{
try
{
string message = Encoding.UTF8.GetString(data.Data);
logger.LogDebug("收到WebSocket二进制数据: {Message}", message);
}
catch (Exception ex)
{
logger.LogError(ex, "处理WebSocket二进制数据时发生错误: {Message}, 数据: {Data}", ex.Message, data.ObjToJson());
}
}
public void Stop()
{
try
{
logger.LogInformation("正在停止WebSocket客户端");
webSocket?.Close();
webSocket?.Dispose();
logger.LogInformation("WebSocket客户端已停止");
}
catch (Exception ex)
{
logger.LogError(ex, "停止WebSocket客户端时发生错误: {Message}", ex.Message);
throw;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
Stop();
}
_disposed = true;
}
}
~CustomWebSocketClient()
{
Dispose(false);
}
}
}