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.

143 lines
4.8 KiB

using CoreAgent.Domain.Interfaces.CustomWSClient;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WebSocket4Net;
using WebSocket = WebSocket4Net.WebSocket;
using WebSocketState = WebSocket4Net.WebSocketState;
namespace CoreAgent.Infrastructure.Services.CustomWSClient
{
public class ObserverCustomWebSocketClient : IObserverCustomWebSocketClient, IDisposable
{
private readonly WebSocket _client;
private readonly ILogger _logger;
private readonly BlockingCollection<string> _sendQueue;
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly Task _sendTask;
private bool _disposed;
private const int SEND_INTERVAL_MS = 100; // 发送间隔,可以根据需要调整
public ObserverCustomWebSocketClient(WebSocket client, ILogger logger)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_sendQueue = new BlockingCollection<string>();
_cancellationTokenSource = new CancellationTokenSource();
_sendTask = Task.Run(ProcessSendQueue);
_logger.LogInformation("WebSocket消息发送队列已启动");
}
public void SendMessage(string message)
{
if (string.IsNullOrEmpty(message))
{
_logger.LogWarning("尝试发送空消息");
return;
}
try
{
_logger.LogDebug("将消息加入发送队列: {Message}", message);
_sendQueue.Add(message);
}
catch (Exception ex)
{
_logger.LogError(ex, "将消息加入发送队列时发生错误: {Message}", message);
throw;
}
}
private async Task ProcessSendQueue()
{
try
{
_logger.LogInformation("开始处理WebSocket消息发送队列");
foreach (var message in _sendQueue.GetConsumingEnumerable(_cancellationTokenSource.Token))
{
try
{
await SendMessageInternalAsync(message);
await Task.Delay(SEND_INTERVAL_MS); // 添加发送间隔
}
catch (Exception ex)
{
_logger.LogError(ex, "发送WebSocket消息时发生错误: {Message}", message);
}
}
}
catch (OperationCanceledException)
{
_logger.LogInformation("WebSocket消息发送队列处理已取消");
}
catch (Exception ex)
{
_logger.LogError(ex, "WebSocket消息发送队列处理过程中发生错误");
}
}
private async Task SendMessageInternalAsync(string message)
{
if (_client.State != WebSocketState.Open)
{
_logger.LogWarning("WebSocket未处于打开状态,无法发送消息。当前状态: {State}, 消息内容: {Message}",
_client.State, message);
return;
}
try
{
_logger.LogDebug("正在发送WebSocket消息: {Message}", message);
await Task.Run(() => _client.Send(message));
_logger.LogDebug("WebSocket消息发送成功");
}
catch (Exception ex)
{
_logger.LogError(ex, "发送WebSocket消息时发生错误: {Message}", message);
throw;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_cancellationTokenSource.Cancel();
_sendQueue.CompleteAdding();
try
{
_sendTask.Wait(TimeSpan.FromSeconds(5));
}
catch (AggregateException ex)
{
_logger.LogError(ex, "等待消息发送队列处理完成时发生错误");
}
_sendQueue.Dispose();
_cancellationTokenSource.Dispose();
}
_disposed = true;
}
}
~ObserverCustomWebSocketClient()
{
Dispose(false);
}
}
}