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.
268 lines
9.1 KiB
268 lines
9.1 KiB
using CoreAgent.WebSocketTransport.Interfaces;
|
|
using CoreAgent.WebSocketTransport.Models;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace CoreAgent.WebSocketTransport.Services;
|
|
|
|
/// <summary>
|
|
/// 消息通道管理器实现
|
|
/// 单一职责:管理所有消息通道
|
|
/// </summary>
|
|
public class MessageChannelManager : IMessageChannelManager
|
|
{
|
|
private readonly ILogger<MessageChannelManager> _logger;
|
|
private volatile bool _disposed;
|
|
private readonly object _disposeLock = new object();
|
|
|
|
private IMessageChannel<ProtocolMessage> _sendChannel;
|
|
private IMessageChannel<object> _receiveChannel;
|
|
private IMessageChannel<HeartbeatMessage> _priorityChannel;
|
|
|
|
public IMessageChannel<ProtocolMessage> SendChannel => _sendChannel;
|
|
public IMessageChannel<object> ReceiveChannel => _receiveChannel;
|
|
public IMessageChannel<HeartbeatMessage> PriorityChannel => _priorityChannel;
|
|
|
|
private readonly int _sendChannelCapacity;
|
|
private readonly int _receiveChannelCapacity;
|
|
private readonly int _priorityChannelCapacity;
|
|
|
|
/// <summary>
|
|
/// 构造函数
|
|
/// </summary>
|
|
/// <param name="logger">日志记录器</param>
|
|
/// <param name="sendChannelCapacity">发送通道容量</param>
|
|
/// <param name="receiveChannelCapacity">接收通道容量</param>
|
|
/// <param name="priorityChannelCapacity">优先级通道容量</param>
|
|
public MessageChannelManager(
|
|
ILogger<MessageChannelManager> logger,
|
|
int sendChannelCapacity,
|
|
int receiveChannelCapacity,
|
|
int priorityChannelCapacity)
|
|
{
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
|
|
// 验证容量参数
|
|
if (sendChannelCapacity <= 0)
|
|
throw new ArgumentOutOfRangeException(nameof(sendChannelCapacity), "发送通道容量必须大于0");
|
|
if (receiveChannelCapacity <= 0)
|
|
throw new ArgumentOutOfRangeException(nameof(receiveChannelCapacity), "接收通道容量必须大于0");
|
|
if (priorityChannelCapacity <= 0)
|
|
throw new ArgumentOutOfRangeException(nameof(priorityChannelCapacity), "优先级通道容量必须大于0");
|
|
|
|
_sendChannelCapacity = sendChannelCapacity;
|
|
_receiveChannelCapacity = receiveChannelCapacity;
|
|
_priorityChannelCapacity = priorityChannelCapacity;
|
|
|
|
_logger.LogInformation("消息通道管理器已创建 - 发送通道容量: {SendCapacity}, 接收通道容量: {ReceiveCapacity}, 优先级通道容量: {PriorityCapacity}",
|
|
sendChannelCapacity, receiveChannelCapacity, priorityChannelCapacity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建所有通道
|
|
/// </summary>
|
|
public void CreateChannels()
|
|
{
|
|
ThrowIfDisposed();
|
|
|
|
try
|
|
{
|
|
// 检查通道是否已存在,如果存在则先释放
|
|
if (_sendChannel != null || _receiveChannel != null || _priorityChannel != null)
|
|
{
|
|
_logger.LogWarning("通道已存在,先释放现有通道");
|
|
ReleaseChannels();
|
|
}
|
|
|
|
_sendChannel = new ChannelMessageChannel<ProtocolMessage>(_sendChannelCapacity);
|
|
_receiveChannel = new ChannelMessageChannel<object>(_receiveChannelCapacity);
|
|
_priorityChannel = new ChannelMessageChannel<HeartbeatMessage>(_priorityChannelCapacity);
|
|
|
|
_logger.LogInformation("所有通道已创建 - 发送通道容量: {SendCapacity}, 接收通道容量: {ReceiveCapacity}, 优先级通道容量: {PriorityCapacity}",
|
|
_sendChannelCapacity, _receiveChannelCapacity, _priorityChannelCapacity);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "创建通道失败");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 释放所有通道(完全释放资源)
|
|
/// </summary>
|
|
public void ReleaseChannels()
|
|
{
|
|
try
|
|
{
|
|
_logger.LogDebug("开始释放所有通道资源");
|
|
|
|
// 检查是否有通道需要释放
|
|
if (_sendChannel == null && _receiveChannel == null && _priorityChannel == null)
|
|
{
|
|
_logger.LogDebug("没有通道需要释放");
|
|
return;
|
|
}
|
|
|
|
// 先完成所有通道(标记不再接受新消息)
|
|
if (_sendChannel != null && !_sendChannel.IsCompleted)
|
|
_sendChannel.Complete();
|
|
if (_receiveChannel != null && !_receiveChannel.IsCompleted)
|
|
_receiveChannel.Complete();
|
|
if (_priorityChannel != null && !_priorityChannel.IsCompleted)
|
|
_priorityChannel.Complete();
|
|
|
|
// 然后释放通道资源
|
|
_sendChannel?.Dispose();
|
|
_receiveChannel?.Dispose();
|
|
_priorityChannel?.Dispose();
|
|
|
|
// 清空引用
|
|
_sendChannel = null;
|
|
_receiveChannel = null;
|
|
_priorityChannel = null;
|
|
|
|
_logger.LogInformation("所有通道资源已完全释放");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "释放通道资源失败");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取通道状态信息
|
|
/// </summary>
|
|
public ChannelStatusInfo GetStatusInfo()
|
|
{
|
|
ThrowIfDisposed();
|
|
|
|
try
|
|
{
|
|
return new ChannelStatusInfo
|
|
{
|
|
SendChannelCount = SendChannel.Count,
|
|
ReceiveChannelCount = ReceiveChannel.Count,
|
|
PriorityChannelCount = PriorityChannel.Count,
|
|
SendChannelCapacity = SendChannel.Capacity,
|
|
ReceiveChannelCapacity = ReceiveChannel.Capacity,
|
|
PriorityChannelCapacity = PriorityChannel.Capacity,
|
|
SendChannelCompleted = SendChannel.IsCompleted,
|
|
ReceiveChannelCompleted = ReceiveChannel.IsCompleted,
|
|
PriorityChannelCompleted = PriorityChannel.IsCompleted
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "获取通道状态信息失败");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 清空所有通道中的消息(保持通道可用)
|
|
/// </summary>
|
|
public void ClearAllChannels()
|
|
{
|
|
ThrowIfDisposed();
|
|
|
|
try
|
|
{
|
|
// 检查通道是否存在
|
|
if (_sendChannel == null && _receiveChannel == null && _priorityChannel == null)
|
|
{
|
|
_logger.LogWarning("通道不存在,跳过清空操作");
|
|
return;
|
|
}
|
|
|
|
// 清空各个通道中的消息
|
|
if (_sendChannel != null)
|
|
_sendChannel.Clear();
|
|
if (_receiveChannel != null)
|
|
_receiveChannel.Clear();
|
|
if (_priorityChannel != null)
|
|
_priorityChannel.Clear();
|
|
|
|
_logger.LogInformation("所有通道中的消息已清空");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "清空通道消息失败");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 完成所有通道(标记不再接受新消息,但保持可读)
|
|
/// </summary>
|
|
public void CompleteAllChannels()
|
|
{
|
|
ThrowIfDisposed();
|
|
|
|
try
|
|
{
|
|
// 检查通道是否存在
|
|
if (_sendChannel == null && _receiveChannel == null && _priorityChannel == null)
|
|
{
|
|
_logger.LogWarning("通道不存在,跳过完成操作");
|
|
return;
|
|
}
|
|
|
|
// 完成各个通道(标记不再接受新消息)
|
|
if (_sendChannel != null && !_sendChannel.IsCompleted)
|
|
_sendChannel.Complete();
|
|
if (_receiveChannel != null && !_receiveChannel.IsCompleted)
|
|
_receiveChannel.Complete();
|
|
if (_priorityChannel != null && !_priorityChannel.IsCompleted)
|
|
_priorityChannel.Complete();
|
|
|
|
_logger.LogInformation("所有通道已完成(不再接受新消息)");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "完成通道失败");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 释放资源
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
lock (_disposeLock)
|
|
{
|
|
if (!_disposed)
|
|
{
|
|
_disposed = true;
|
|
|
|
try
|
|
{
|
|
// 释放所有通道
|
|
ReleaseChannels();
|
|
|
|
_logger.LogInformation("消息通道管理器已释放");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "释放消息通道管理器时发生异常");
|
|
}
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查是否已释放
|
|
/// </summary>
|
|
private void ThrowIfDisposed()
|
|
{
|
|
if (_disposed)
|
|
{
|
|
throw new ObjectDisposedException(nameof(MessageChannelManager));
|
|
}
|
|
}
|
|
}
|