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.

200 lines
6.9 KiB

using CoreAgent.ProtocolClient.Models;
using CoreAgent.ProtocolClient.ProtocolEngineCore;
using CoreAgent.ProtocolClient.ProtocolWsClient;
using CoreAgent.ProtocolClient.Interfaces;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network
{
/// <summary>
/// 协议WebSocket客户端管理器
/// 负责启动和停止所有协议客户端
/// </summary>
public class ProtocolWsClientManager : IProtocolWsClientManager
{
private readonly ILogger<ProtocolWsClientManager> _logger;
private readonly IProtocolLogObserver _protocolLogObserver;
private readonly Dictionary<string, ProtocolWsClient> _clients;
private readonly ILoggerFactory _loggerFactory;
private readonly object _lock = new object();
private bool _disposed = false;
public ProtocolWsClientManager(
ILogger<ProtocolWsClientManager> logger,
IProtocolLogObserver protocolLogObserver,
ILoggerFactory loggerFactory)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
_clients = new Dictionary<string, ProtocolWsClient>();
}
/// <summary>
/// 创建ProtocolWsClient实例
/// </summary>
/// <param name="config">协议客户端配置</param>
/// <returns>ProtocolWsClient实例</returns>
private ProtocolWsClient CreateProtocolWsClient(ProtocolClientConfig config)
{
if (config == null)
throw new ArgumentNullException(nameof(config));
if (string.IsNullOrEmpty(config.Name))
throw new ArgumentException("配置名称不能为空", nameof(config));
_logger.LogInformation("创建ProtocolWsClient实例: {ClientName}", config.Name);
return new ProtocolWsClient(config, _loggerFactory, _protocolLogObserver);
}
/// <summary>
/// 启动所有协议客户端
/// </summary>
/// <param name="configs">协议客户端配置数组</param>
public void StartAllClients(ProtocolClientConfig[] configs)
{
ThrowIfDisposed();
if (configs == null || configs.Length == 0)
{
_logger.LogWarning("没有可用的协议客户端配置");
return;
}
lock (_lock)
{
_logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", configs.Length);
var startedCount = 0;
var failedCount = 0;
foreach (var config in configs)
{
try
{
if (!_clients.ContainsKey(config.Name))
{
var client = CreateProtocolWsClient(config);
_clients[config.Name] = client;
}
var existingClient = _clients[config.Name];
existingClient.Start();
startedCount++;
_logger.LogInformation("启动协议客户端成功: {ClientName}", config.Name);
}
catch (Exception ex)
{
failedCount++;
_logger.LogError(ex, "启动协议客户端失败: {ClientName}", config.Name);
}
}
_logger.LogInformation("协议客户端启动完成 - 成功: {StartedCount}, 失败: {FailedCount}", startedCount, failedCount);
}
}
/// <summary>
/// 停止所有协议客户端
/// </summary>
public void StopAllClients()
{
lock (_lock)
{
if (_clients.Count == 0)
{
_logger.LogInformation("没有运行中的协议客户端");
return;
}
_logger.LogInformation("开始停止所有协议客户端,客户端数量: {ClientCount}", _clients.Count);
var stoppedCount = 0;
var failedCount = 0;
foreach (var kvp in _clients)
{
try
{
kvp.Value.Stop();
stoppedCount++;
_logger.LogInformation("停止协议客户端成功: {ClientName}", kvp.Key);
}
catch (Exception ex)
{
failedCount++;
_logger.LogError(ex, "停止协议客户端失败: {ClientName}", kvp.Key);
}
}
_logger.LogInformation("协议客户端停止完成 - 成功: {StoppedCount}, 失败: {FailedCount}", stoppedCount, failedCount);
}
}
/// <summary>
/// 释放所有客户端资源
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 释放资源
/// </summary>
/// <param name="disposing">是否正在释放托管资源</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
lock (_lock)
{
StopAllClients();
var disposedCount = 0;
var failedCount = 0;
foreach (var client in _clients.Values)
{
try
{
client.Dispose();
disposedCount++;
}
catch (Exception ex)
{
failedCount++;
_logger.LogError(ex, "释放客户端资源失败");
}
}
_clients.Clear();
_logger.LogInformation("协议客户端管理器释放完成 - 成功: {DisposedCount}, 失败: {FailedCount}", disposedCount, failedCount);
}
}
_disposed = true;
}
/// <summary>
/// 检查是否已释放
/// </summary>
private void ThrowIfDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(ProtocolWsClientManager));
}
}
}
}