Browse Source

优化ProtocolWsClientManager:简化接口,专注核心功能

- 移除不必要的公共方法(AddAndStartClient、GetAllClients、GetClient等)
- 保留核心功能:StartAllClients和StopAllClients
- 将CreateProtocolWsClient改为私有方法
- 更新类注释,明确单一职责
- 保持线程安全和资源管理
feature/protocol-log-Perfect
root 1 week ago
parent
commit
ec120aeb19
  1. 2
      CoreAgent.Infrastructure/CoreAgent.Infrastructure.csproj
  2. 27
      CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
  3. 59
      CoreAgent.Infrastructure/Services/Network/ProtocolClientConfigFactory.cs
  4. 202
      CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
  5. 17
      CoreAgent.ProtocolClient/ProtocolEngineCore/IProtocolLogObserver.cs
  6. 25
      CoreAgent.ProtocolClient/ProtocolEngineCore/ProtocolLogProcessor.cs
  7. 2
      CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Connection.cs
  8. 6
      CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Core.cs
  9. 2
      CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Events.cs
  10. 6
      CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Interface.cs
  11. 6
      CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.MessageDispatch.cs
  12. 128
      CoreAgent.ProtocolClient/modify.md

2
CoreAgent.Infrastructure/CoreAgent.Infrastructure.csproj

@ -25,6 +25,8 @@
<ItemGroup>
<ProjectReference Include="..\CoreAgent.Domain\CoreAgent.Domain.csproj" />
<ProjectReference Include="..\CoreAgent.ProtocolClient\CoreAgent.ProtocolClient.csproj" />
<ProjectReference Include="..\CoreAgent.WebSocketTransport\CoreAgent.WebSocketTransport.csproj" />
</ItemGroup>
</Project>

27
CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CoreAgent.ProtocolClient.Models;
using CoreAgent.ProtocolClient.ProtocolEngineCore;
using CoreAgent.WebSocketTransport.Interfaces;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network
{
public class NetworkProtocolLogObserver : IProtocolLogObserver
{
private readonly ILogger<NetworkProtocolLogObserver> _logger;
private readonly IMessageChannelManager _ChannelManager;
public NetworkProtocolLogObserver(ILogger<NetworkProtocolLogObserver> logger, IMessageChannelManager channelManager)
{
this._logger = logger;
this._ChannelManager = channelManager;
}
public void OnProtocolLogsReceived(IEnumerable<TransferProtocolLog> logDetails)
{
_ChannelManager.SendChannel.TryWrite(logDetails);
}
}
}

59
CoreAgent.Infrastructure/Services/Network/ProtocolClientConfigFactory.cs

@ -0,0 +1,59 @@
using CoreAgent.ProtocolClient.Models;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network
{
/// <summary>
/// 协议客户端配置工厂
/// 负责从其他实体组装ProtocolClientConfig
/// </summary>
public class ProtocolClientConfigFactory
{
private readonly ILogger<ProtocolClientConfigFactory> _logger;
private readonly List<ProtocolClientConfig> _configs;
public ProtocolClientConfigFactory(ILogger<ProtocolClientConfigFactory> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_configs = new List<ProtocolClientConfig>();
}
/// <summary>
/// 从多个实体创建协议客户端配置数组
/// </summary>
/// <param name="entities">实体列表</param>
/// <returns>协议客户端配置数组</returns>
public ProtocolClientConfig[] CreateFromEntities(IEnumerable<object> entities)
{
// TODO: 实现从多个实体组装ProtocolClientConfig数组的逻辑
_logger.LogInformation("从多个实体创建协议客户端配置数组");
// 清空现有配置
_configs.Clear();
// TODO: 实现具体的组装逻辑
// foreach (var entity in entities)
// {
// var config = CreateConfigFromEntity(entity);
// _configs.Add(config);
// }
throw new NotImplementedException("需要实现从多个实体创建协议客户端配置数组的逻辑");
}
/// <summary>
/// 获取所有协议客户端配置
/// </summary>
/// <returns>协议客户端配置数组</returns>
public ProtocolClientConfig[] GetAllConfigs()
{
_logger.LogInformation("获取所有协议客户端配置,数量: {Count}", _configs.Count);
return _configs.ToArray();
}
/// <summary>
/// 获取配置数量
/// </summary>
public int ConfigCount => _configs.Count;
}
}

202
CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs

@ -0,0 +1,202 @@
using CoreAgent.ProtocolClient.Models;
using CoreAgent.ProtocolClient.ProtocolEngineCore;
using CoreAgent.ProtocolClient.ProtocolWsClient;
using Microsoft.Extensions.Logging;
namespace CoreAgent.Infrastructure.Services.Network
{
/// <summary>
/// 协议WebSocket客户端管理器
/// 负责启动和停止所有协议客户端
/// </summary>
public class ProtocolWsClientManager : IDisposable
{
private readonly ILogger<ProtocolWsClientManager> _logger;
private readonly IProtocolLogObserver _protocolLogObserver;
private readonly ProtocolClientConfigFactory _configFactory;
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,
ProtocolClientConfigFactory configFactory,
ILoggerFactory loggerFactory)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
_configFactory = configFactory ?? throw new ArgumentNullException(nameof(configFactory));
_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>
public void StartAllClients()
{
ThrowIfDisposed();
lock (_lock)
{
_logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", _configFactory.ConfigCount);
var configs = _configFactory.GetAllConfigs();
if (configs.Length == 0)
{
_logger.LogWarning("没有可用的协议客户端配置");
return;
}
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));
}
}
}
}

17
CoreAgent.ProtocolClient/ProtocolEngineCore/IProtocolLogObserver.cs

@ -0,0 +1,17 @@
using CoreAgent.ProtocolClient.Models;
namespace CoreAgent.ProtocolClient.ProtocolEngineCore
{
/// <summary>
/// 协议日志观察者接口
/// 用于观察和处理转换后的协议日志数据
/// </summary>
public interface IProtocolLogObserver
{
/// <summary>
/// 处理协议日志详情
/// </summary>
/// <param name="logDetails">协议日志详情列表</param>
void OnProtocolLogsReceived(IEnumerable<TransferProtocolLog> logDetails);
}
}

25
CoreAgent.ProtocolClient/ProtocolEngineCore/LogManager.cs → CoreAgent.ProtocolClient/ProtocolEngineCore/ProtocolLogProcessor.cs

@ -13,13 +13,14 @@ using Microsoft.Extensions.Logging;
namespace CoreAgent.ProtocolClient.ProtocolEngineCore
{
/// <summary>
/// 管理所有与日志相关的操作。
/// 协议日志处理器
/// 职责:
/// 1. 管理日志队列和消费任务
/// 2. 协调日志解析和数据转换
/// 3. 提供统一的日志处理接口
/// 1. 管理协议日志队列和消费任务
/// 2. 协调协议日志解析和数据转换
/// 3. 提供统一的协议日志处理接口
/// 4. 处理协议栈各层日志(RRC、NAS、SIP等)
/// </summary>
public class LogManager
public class ProtocolLogProcessor
{
private readonly ProtocolClientConfig _config;
private readonly ProtocolClientContext _context;
@ -32,8 +33,9 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
private readonly ProtocolContextParser? _contextParser;
private readonly LogMessageHandler _messageHandler;
private readonly LogDataConverter _dataConverter;
private readonly IProtocolLogObserver _protocolLogObserver;
public LogManager(ProtocolClientConfig config, ProtocolClientContext context, ILogger logger, WebSocketMessageManager messageManager, CancellationToken cancellationToken = default)
public ProtocolLogProcessor(ProtocolClientConfig config, ProtocolClientContext context, ILogger logger, WebSocketMessageManager messageManager, IProtocolLogObserver protocolLogObserver, CancellationToken cancellationToken = default)
{
_config = config;
_context = context;
@ -44,6 +46,7 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
_contextParser = new ProtocolContextParser(context);
_messageHandler = new LogMessageHandler(config, context, logger, messageManager);
_dataConverter = new LogDataConverter(context, logger);
_protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
// 订阅日志接收事件
_messageHandler.OnLogReceived += HandleLogReceived;
@ -156,6 +159,16 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
_logger.LogError(ex, $"处理日志详情失败: Layer={detail.LayerType}, UEID={detail.UEID}");
}
}
// 通知协议日志观察者处理转换后的数据
try
{
_protocolLogObserver.OnProtocolLogsReceived(logDetails);
}
catch (Exception ex)
{
_logger.LogError(ex, "通知协议日志观察者失败");
}
}
#region 公共接口 - 委托给消息处理器

2
CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Connection.cs

@ -34,7 +34,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
_messageManager.ResetLogGetId();
SetState(ClientState.Stop);
StopTimers();
_logManager.Stop();
_protocolLogProcessor.Stop();
_isReady = false;
_logger.LogDebug($"[{_config.Name}] 停止连接");
}

6
CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Core.cs

@ -28,7 +28,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
#region 管理器
private readonly AuthenticationManager _authManager;
private readonly LogManager _logManager;
private readonly ProtocolLogProcessor _protocolLogProcessor;
private readonly StatsManager _statsManager;
private readonly MessageHandlerManager _handlerManager;
#endregion
@ -46,7 +46,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
public ProtocolClientConfig Config => _config;
#endregion
public ProtocolWsClient(ProtocolClientConfig config, ILoggerFactory loggerFactory)
public ProtocolWsClient(ProtocolClientConfig config, ILoggerFactory loggerFactory, IProtocolLogObserver protocolLogObserver)
{
_config = config;
_logger = loggerFactory.CreateLogger<ProtocolWsClient>();
@ -54,7 +54,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
_messageManager = new WebSocketMessageManager(config.Name, loggerFactory);
_authManager = new AuthenticationManager(_config, _logger, (msg) => _messageManager.SendMessage(msg));
_statsManager = new StatsManager(_config.Name, _logger, (msg, cb, err) => _messageManager.SendMessage(msg, cb, err));
_logManager = new LogManager(_config, _context, _logger, _messageManager);
_protocolLogProcessor = new ProtocolLogProcessor(_config, _context, _logger, _messageManager, protocolLogObserver);
_handlerManager = new MessageHandlerManager(_messageManager, (msg, cb, err) => _messageManager.SendMessage(msg, cb, err));
SubscribeToEvents();
}

2
CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Events.cs

@ -50,7 +50,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
StopTimers();
_isReady = false;
_authManager.Reset();
_logManager.Stop();
_protocolLogProcessor.Stop();
_messageManager.ResetLogGetId();
if (State == ClientState.Connected) { }
if (_config.Enabled && State != ClientState.Stop)

6
CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Interface.cs

@ -11,9 +11,9 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
public partial class ProtocolWsClient
{
#region 业务接口实现
public void ResetLogs() => _logManager.ResetLogs();
public void SetLogsConfig(ProtocolClientLogsConfig logsConfig, bool save = false) => _logManager.SetLogsConfig(logsConfig, save);
public void LogGet(Dictionary<string, object>? parameters = null) => _logManager.GetLogs(parameters);
public void ResetLogs() => _protocolLogProcessor.ResetLogs();
public void SetLogsConfig(ProtocolClientLogsConfig logsConfig, bool save = false) => _protocolLogProcessor.SetLogsConfig(logsConfig, save);
public void LogGet(Dictionary<string, object>? parameters = null) => _protocolLogProcessor.GetLogs(parameters);
public void TriggerStatsUpdate() => _statsManager.TriggerStatsUpdate();
public void ResetStatistics() => _statsManager.ResetStatistics();
public void SetStatisticsConfig(bool enableSamples, bool enableRf) => _statsManager.SetStatisticsConfig(enableSamples, enableRf);

6
CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.MessageDispatch.cs

@ -25,7 +25,7 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
_authManager.HandleMessage(message);
return;
}
_logManager.HandleMessage(message);
_protocolLogProcessor.HandleMessage(message);
_statsManager.HandleMessage(message);
}
@ -63,11 +63,11 @@ namespace CoreAgent.ProtocolClient.ProtocolWsClient
SetState(ClientState.Connected);
if (ro)
{
_logManager.GetLogs(new Dictionary<string, object> { ["timeout"] = 0 });
_protocolLogProcessor.GetLogs(new Dictionary<string, object> { ["timeout"] = 0 });
}
else
{
_logManager.SetLogsConfig(_config.Logs);
_protocolLogProcessor.SetLogsConfig(_config.Logs);
}
_statsManager.Start(true);
});

128
CoreAgent.ProtocolClient/modify.md

@ -1439,4 +1439,130 @@ public class ProtocolClientConfig
- **扩展性好**:为未来可能的其他类型客户端配置留出空间
- **符合最佳实践**:遵循C#命名约定和领域驱动设计原则
**提交信息:** 重命名ClientConfig为ProtocolClientConfig,明确协议客户端配置用途
**提交信息:** 重命名ClientConfig为ProtocolClientConfig,明确协议客户端配置用途
## 2024-12-19
### 规范LogManager命名并添加协议日志观察者接口
**修改内容:**
1. **重命名LogManager为ProtocolLogProcessor**
- 文件名:`LogManager.cs` → `ProtocolLogProcessor.cs`
- 类名:`LogManager` → `ProtocolLogProcessor`
- 更新所有相关引用
2. **添加协议日志观察者接口**
- 创建 `IProtocolLogObserver` 接口
- 在 `ProtocolLogProcessor` 中集成观察者模式
**涉及文件:**
- `CoreAgent.ProtocolClient/ProtocolEngineCore/LogManager.cs``ProtocolLogProcessor.cs`
- `CoreAgent.ProtocolClient/ProtocolEngineCore/IProtocolLogObserver.cs` - 新增观察者接口
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Core.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Interface.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Events.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.MessageDispatch.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Connection.cs`
**主要改进:**
1. **命名规范**:`ProtocolLogProcessor` 更准确地反映了类的职责
2. **观察者模式**:使用 `IProtocolLogObserver` 接口实现数据转发
3. **强制依赖**:观察者不能为空,确保数据处理的可靠性
**修改对比:**
```csharp
// 修改前:通用名称,不够明确
public class LogManager
{
// 处理日志相关操作
}
// 修改后:明确表示协议日志处理器
public class ProtocolLogProcessor
{
private readonly IProtocolLogObserver _protocolLogObserver;
public ProtocolLogProcessor(..., IProtocolLogObserver protocolLogObserver)
{
_protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
}
}
```
**设计优势:**
- **命名明确**:清楚表达这是协议日志处理器
- **观察者模式**:支持多个观察者处理协议日志数据
- **强制依赖**:确保观察者必须存在,避免空引用
- **扩展性好**:可以轻松添加新的观察者实现
- **职责清晰**:专门处理协议相关的日志数据
**提交信息:** 规范LogManager命名为ProtocolLogProcessor,添加协议日志观察者接口支持数据转发
## 2024-12-19
### 规范LogManager命名并添加协议日志观察者接口
**修改内容:**
1. **类名重命名**
- `LogManager``ProtocolLogProcessor` (协议日志处理器)
- 文件名:`LogManager.cs` → `ProtocolLogProcessor.cs`
- 更新所有相关引用
2. **添加协议日志观察者接口**
- 创建 `IProtocolLogObserver` 接口
- 在 `ProtocolLogProcessor` 中集成观察者模式
- 支持转发处理后的 `TransferProtocolLog` 数据
**涉及文件:**
- `CoreAgent.ProtocolClient/ProtocolEngineCore/LogManager.cs``ProtocolLogProcessor.cs`
- `CoreAgent.ProtocolClient/ProtocolEngineCore/IProtocolLogObserver.cs` - 新增观察者接口
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Core.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Interface.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Events.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.MessageDispatch.cs`
- `CoreAgent.ProtocolClient/ProtocolWsClient/ProtocolWsClient.Connection.cs`
- `CoreAgent.ProtocolClient/项目结构说明.md`
**主要改进:**
1. **命名规范**:`ProtocolLogProcessor` 更准确地反映了类的职责
2. **职责明确**:专门处理协议相关的日志数据
3. **观察者模式**:通过 `IProtocolLogObserver` 接口支持扩展和依赖注入
4. **数据转发**:支持将处理后的 `TransferProtocolLog` 数据转发给其他组件
5. **同步处理**:使用同步方法处理日志数据
6. **错误处理**:完善的异常处理和日志记录
**修改对比:**
```csharp
// 修改前:通用名称,不够明确
public class LogManager
{
// 管理所有与日志相关的操作
}
// 修改后:明确表示协议日志处理器
public class ProtocolLogProcessor
{
// 专门处理协议相关的日志数据
}
// 新增观察者接口
public interface IProtocolLogObserver
{
void OnProtocolLogsReceived(IEnumerable<TransferProtocolLog> logDetails);
}
```
**设计优势:**
- **命名明确**:清楚表达这是协议日志处理器
- **职责清晰**:专门处理协议栈各层日志(RRC、NAS、SIP等)
- **观察者模式**:支持多个观察者处理同一份日志数据
- **扩展性好**:可以轻松添加新的日志处理逻辑
- **解耦合**:日志处理与具体业务逻辑分离
- **符合最佳实践**:遵循C#命名约定和设计模式
**使用场景:**
1. **实时日志处理**:处理从WebSocket接收的实时协议日志
2. **数据转发**:将处理后的日志数据转发给数据库、消息队列等
3. **业务分析**:支持上层业务对协议日志进行分析和处理
4. **监控告警**:基于协议日志进行网络监控和告警
**提交信息:** 规范LogManager命名为ProtocolLogProcessor,添加协议日志观察者接口支持数据转发
Loading…
Cancel
Save