diff --git a/CoreAgent.API/Configurations/websocket.json b/CoreAgent.API/Configurations/websocket.json index 7965961..3f3662a 100644 --- a/CoreAgent.API/Configurations/websocket.json +++ b/CoreAgent.API/Configurations/websocket.json @@ -5,7 +5,7 @@ "BatchTimeoutMs": 100, "MaxBatchSize": 100, "MaxReconnectAttempts": 5, - "QueueCapacity": 1000, + "QueueCapacity": 10000, "CacheTtlMinutes": 30 } } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs index b1d2070..c37e5a8 100644 --- a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs +++ b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs @@ -6,6 +6,8 @@ using CoreAgent.Infrastructure.Contexts; using CoreAgent.Infrastructure.Repositories; using CoreAgent.Infrastructure.Services; using CoreAgent.Infrastructure.Services.Network; +using CoreAgent.ProtocolClient.Interfaces; +using CoreAgent.ProtocolClient.ProtocolEngineCore; using Microsoft.Extensions.DependencyInjection; namespace CoreAgent.Infrastructure.Extensions.ServiceCollection; @@ -39,7 +41,8 @@ public static class CommandServiceExtensions services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - + services.AddSingleton(); + services.AddSingleton(); // 注册命令执行器(瞬时) services.AddTransient(sp => { diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs index 057e846..cd2ee51 100644 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs +++ b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs @@ -6,6 +6,9 @@ using CoreAgent.Domain.Interfaces.System.Command; using CoreAgent.Domain.Models.Network; using CoreAgent.Domain.Models.System; using CoreAgent.Infrastructure.Services.Network; +using CoreAgent.WebSocketTransport.Interfaces; +using CoreAgent.ProtocolClient.ProtocolEngineCore; +using CoreAgent.ProtocolClient.Interfaces; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.IO; @@ -25,9 +28,12 @@ public class CellularNetworkService : ICellularNetworkService private readonly INetworkConfigCopier _configCopier; private readonly INetworkInterfaceManager _interfaceManager; private readonly INetworkStatusMonitor _statusMonitor; + private readonly IWebSocketTransport _webSocketTransport; + private readonly IProtocolLogObserver _protocolLogObserver; + private readonly IProtocolWsClientManager _protocolWsClientManager; private static readonly SemaphoreSlim _startLock = new(1, 1); private const int LockTimeoutSeconds = 60; - + public CellularNetworkService( ILogger logger, @@ -37,7 +43,10 @@ public class CellularNetworkService : ICellularNetworkService ICellularNetworkContext context, INetworkConfigCopier configCopier, INetworkInterfaceManager interfaceManager, - INetworkStatusMonitor statusMonitor) + INetworkStatusMonitor statusMonitor, + IWebSocketTransport webSocketTransport, + IProtocolLogObserver protocolLogObserver, + IProtocolWsClientManager protocolWsClientManager) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); @@ -47,6 +56,9 @@ public class CellularNetworkService : ICellularNetworkService _configCopier = configCopier ?? throw new ArgumentNullException(nameof(configCopier)); _interfaceManager = interfaceManager ?? throw new ArgumentNullException(nameof(interfaceManager)); _statusMonitor = statusMonitor; + _webSocketTransport = webSocketTransport ?? throw new ArgumentNullException(nameof(webSocketTransport)); + _protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver)); + _protocolWsClientManager = protocolWsClientManager ?? throw new ArgumentNullException(nameof(protocolWsClientManager)); } /// @@ -163,7 +175,28 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure(disableResult.ErrorMessage); } - // 5. 收集所有网络端点信息 + // 5. 停止所有协议客户端 + try + { + _logger.LogInformation("开始停止所有协议客户端"); + _protocolWsClientManager.StopAllClients(); + _logger.LogInformation("所有协议客户端停止完成"); + } + catch (Exception ex) + { + _logger.LogError(ex, "停止协议客户端失败"); + // 不返回失败,继续执行后续步骤 + } + + // 6. 停止 WebSocket 传输连接 + var webSocketConnected = await StopWebSocketTransportAsync(); + if (!webSocketConnected) + { + _logger.LogError("WebSocket 传输连接停止失败,服务端可能未启动"); + return CellularNetworkOperationResult.Failure("WebSocket 传输连接停止失败"); + } + _logger.LogInformation("WebSocket 传输连接停止成功"); + // 7. 收集所有网络端点信息 var endPoints = new NetworkIPEndPointCollection { RanEndPoint = _context.NetworkIPEndPointManager.GetRanEndPoint(), @@ -171,7 +204,7 @@ public class CellularNetworkService : ICellularNetworkService CnEndPoints = _context.NetworkIPEndPointManager.GetCnEndPoints() }; - // 6. 检查网络端点连接状态 + // 8. 检查网络端点连接状态 _logger.LogInformation("开始检查所有网络端点的连接状态"); var statusCheckResult = await _statusMonitor.CheckAllEndPointsStatusAsync(endPoints, _context.CurrentConfigType, isStartOperation:false); if (!statusCheckResult.IsSuccess) @@ -180,7 +213,7 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure("网络端点仍然处于连接状态,停止操作失败"); } - // 7. 重置上下文并返回成功结果 + // 9. 重置上下文并返回成功结果 _context.Reset(); return CellularNetworkOperationResult.Success(NetworkStatus.Disconnected); } @@ -239,7 +272,13 @@ public class CellularNetworkService : ICellularNetworkService private async Task StartNetworkAsync(string key) { + var startTime = DateTime.UtcNow; + _logger.LogInformation("开始启动网络配置 {ConfigKey},开始时间: {StartTime}", key, startTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); + // 1. 获取并验证网络配置 + var step1Start = DateTime.UtcNow; + _logger.LogDebug("步骤1开始:获取并验证网络配置"); + var config = await _configService.GetByConfigKeyAsync(key); if (config == null) { @@ -247,15 +286,27 @@ public class CellularNetworkService : ICellularNetworkService _logger.LogError(message); return CellularNetworkOperationResult.Failure(message); } + + var step1Duration = (DateTime.UtcNow - step1Start).TotalMilliseconds; + _logger.LogDebug("步骤1完成:获取并验证网络配置,耗时: {Duration}ms", step1Duration.ToString("F2")); // 2. 执行网络接口初始化命令 + var step2Start = DateTime.UtcNow; + _logger.LogDebug("步骤2开始:执行网络接口初始化命令"); + var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync(true); if (!initResult.IsSuccess) { _logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage); } + + var step2Duration = (DateTime.UtcNow - step2Start).TotalMilliseconds; + _logger.LogDebug("步骤2完成:执行网络接口初始化命令,耗时: {Duration}ms", step2Duration.ToString("F2")); // 3. 复制配置值到临时目录 + var step3Start = DateTime.UtcNow; + _logger.LogDebug("步骤3开始:复制配置值到临时目录"); + var copyResult = await _configCopier.CopyConfigValuesToTempAsync(config, _context.GetAppSettings()); if (!copyResult.IsSuccess) { @@ -263,8 +314,14 @@ public class CellularNetworkService : ICellularNetworkService _logger.LogError(message); return CellularNetworkOperationResult.Failure(message); } + + var step3Duration = (DateTime.UtcNow - step3Start).TotalMilliseconds; + _logger.LogDebug("步骤3完成:复制配置值到临时目录,耗时: {Duration}ms", step3Duration.ToString("F2")); // 4. 获取并验证 IP 端点信息 + var step4Start = DateTime.UtcNow; + _logger.LogDebug("步骤4开始:获取并验证 IP 端点信息"); + var (endPoints, hasAnyEndPoint) = await _configCopier.GetComAddrInfoAsync(config); if (!hasAnyEndPoint) { @@ -272,11 +329,23 @@ public class CellularNetworkService : ICellularNetworkService _logger.LogError(message); return CellularNetworkOperationResult.Failure(message); } + + var step4Duration = (DateTime.UtcNow - step4Start).TotalMilliseconds; + _logger.LogDebug("步骤4完成:获取并验证 IP 端点信息,耗时: {Duration}ms", step4Duration.ToString("F2")); // 5. 更新 IP 端点管理器 + var step5Start = DateTime.UtcNow; + _logger.LogDebug("步骤5开始:更新 IP 端点管理器"); + _context.NetworkIPEndPointManager.UpdateEndPoints(endPoints); - - // 5.5. 创建协议客户端配置 + + var step5Duration = (DateTime.UtcNow - step5Start).TotalMilliseconds; + _logger.LogDebug("步骤5完成:更新 IP 端点管理器,耗时: {Duration}ms", step5Duration.ToString("F2")); + + // 6. 创建协议客户端配置 + var step6Start = DateTime.UtcNow; + _logger.LogDebug("步骤6开始:创建协议客户端配置"); + var protocolConfigFactory = new ProtocolClientConfigFactory(_loggerFactory.CreateLogger(), _context); var configCreated = protocolConfigFactory.CreateFromEntities(); if (configCreated) @@ -288,9 +357,30 @@ public class CellularNetworkService : ICellularNetworkService _logger.LogWarning("协议客户端配置创建失败"); return CellularNetworkOperationResult.Failure("协议客户端配置创建失败"); } - - // 6. 启动网络配置 + + var step6Duration = (DateTime.UtcNow - step6Start).TotalMilliseconds; + _logger.LogDebug("步骤6完成:创建协议客户端配置,耗时: {Duration}ms", step6Duration.ToString("F2")); + + // 7. 启动 WebSocket 传输连接 + var step7Start = DateTime.UtcNow; + _logger.LogDebug("步骤7开始:启动 WebSocket 传输连接"); + + var webSocketConnected = await StartWebSocketTransportAsync(); + if (!webSocketConnected) + { + _logger.LogError("WebSocket 传输连接启动失败,服务端可能未启动"); + return CellularNetworkOperationResult.Failure("WebSocket 传输连接启动失败,服务端可能未启动"); + } + _logger.LogInformation("WebSocket 传输连接启动成功"); + + var step7Duration = (DateTime.UtcNow - step7Start).TotalMilliseconds; + _logger.LogDebug("步骤7完成:启动 WebSocket 传输连接,耗时: {Duration}ms", step7Duration.ToString("F2")); + + // 8. 启动网络配置 + var step8Start = DateTime.UtcNow; + _logger.LogDebug("步骤8开始:启动网络配置"); _logger.LogInformation("正在启动蜂窝网络配置: {ConfigKey}", key); + var enableResult = await _interfaceManager.EnableAsync(config); if (!enableResult.IsSuccess) { @@ -298,13 +388,25 @@ public class CellularNetworkService : ICellularNetworkService _logger.LogError(message); return CellularNetworkOperationResult.Failure(message); } - - // 7. 更新网络配置类型 + + var step8Duration = (DateTime.UtcNow - step8Start).TotalMilliseconds; + _logger.LogDebug("步骤8完成:启动网络配置,耗时: {Duration}ms", step8Duration.ToString("F2")); + + // 9. 更新网络配置类型 + var step9Start = DateTime.UtcNow; + _logger.LogDebug("步骤9开始:更新网络配置类型"); + _context.UpdateNetworkConfigType(enableResult.ConfigType); _logger.LogInformation("更新网络配置类型: {ConfigType}", enableResult.ConfigType); + + var step9Duration = (DateTime.UtcNow - step9Start).TotalMilliseconds; + _logger.LogDebug("步骤9完成:更新网络配置类型,耗时: {Duration}ms", step9Duration.ToString("F2")); - // 8. 检查网络端点连接状态 + // 10. 检查网络端点连接状态 + var step10Start = DateTime.UtcNow; + _logger.LogDebug("步骤10开始:检查网络端点连接状态"); _logger.LogInformation("开始检查所有网络端点的连接状态"); + var statusCheckResult = await _statusMonitor.CheckAllEndPointsStatusAsync(endPoints, enableResult.ConfigType, isStartOperation:true); if (!statusCheckResult.IsSuccess) { @@ -313,12 +415,83 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure($"网络端点状态检查失败: {errorMessage}"); } _logger.LogInformation("网络端点状态检查完成,所有端点状态正常"); - - // 9. 更新网络状态并返回结果 + + var step10Duration = (DateTime.UtcNow - step10Start).TotalMilliseconds; + _logger.LogDebug("步骤10完成:检查网络端点连接状态,耗时: {Duration}ms", step10Duration.ToString("F2")); + + // 11. 更新网络状态 + var step11Start = DateTime.UtcNow; + _logger.LogDebug("步骤11开始:更新网络状态"); + var state = _context.GetNetworkState(); state.MarkAsStarted(); - _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status}", key, state.CurrentStatus); + + var step11Duration = (DateTime.UtcNow - step11Start).TotalMilliseconds; + _logger.LogDebug("步骤11完成:更新网络状态,耗时: {Duration}ms", step11Duration.ToString("F2")); + + // 12. 启动所有协议客户端 + var step12Start = DateTime.UtcNow; + _logger.LogDebug("步骤12开始:启动所有协议客户端"); + + try + { + var protocolConfigs = protocolConfigFactory.GetAllConfigs(); + _protocolWsClientManager.StartAllClients(protocolConfigs); + _logger.LogInformation("所有协议客户端启动完成"); + } + catch (Exception ex) + { + _logger.LogError(ex, "启动协议客户端失败"); + return CellularNetworkOperationResult.Failure($"启动协议客户端失败: {ex.Message}"); + } + + var step12Duration = (DateTime.UtcNow - step12Start).TotalMilliseconds; + _logger.LogDebug("步骤12完成:启动所有协议客户端,耗时: {Duration}ms", step12Duration.ToString("F2")); + + var endTime = DateTime.UtcNow; + var duration = endTime - startTime; + _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status},总耗时: {Duration}ms", + key, state.CurrentStatus, duration.TotalMilliseconds.ToString("F2")); return CellularNetworkOperationResult.Success(state.CurrentStatus); } + + /// + /// 启动 WebSocket 传输连接 + /// + /// 连接是否成功 + private async Task StartWebSocketTransportAsync() + { + try + { + _logger.LogInformation("开始启动 WebSocket 传输连接"); + await _webSocketTransport.ConnectAsync(); + return _webSocketTransport.IsConnected; + } + catch (Exception ex) + { + _logger.LogError(ex, "WebSocket 传输连接启动失败"); + return false; + } + } + + + /// + /// 停止 WebSocket 传输连接 + /// + /// 停止是否成功 + private async Task StopWebSocketTransportAsync() + { + try + { + _logger.LogInformation("开始停止 WebSocket 传输连接"); + await _webSocketTransport.CloseAsync(); + return !_webSocketTransport.IsConnected; + } + catch (Exception ex) + { + _logger.LogError(ex, "WebSocket 传输连接停止失败"); + return false; + } + } } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs b/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs index fc3fb2b..f1f732b 100644 --- a/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs +++ b/CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs @@ -1,6 +1,7 @@ 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 @@ -9,11 +10,10 @@ namespace CoreAgent.Infrastructure.Services.Network /// 协议WebSocket客户端管理器 /// 负责启动和停止所有协议客户端 /// - public class ProtocolWsClientManager : IDisposable + public class ProtocolWsClientManager : IProtocolWsClientManager { private readonly ILogger _logger; private readonly IProtocolLogObserver _protocolLogObserver; - private readonly ProtocolClientConfigFactory _configFactory; private readonly Dictionary _clients; private readonly ILoggerFactory _loggerFactory; private readonly object _lock = new object(); @@ -22,12 +22,10 @@ namespace CoreAgent.Infrastructure.Services.Network public ProtocolWsClientManager( ILogger 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(); } @@ -55,20 +53,20 @@ namespace CoreAgent.Infrastructure.Services.Network /// /// 启动所有协议客户端 /// - public void StartAllClients() + /// 协议客户端配置数组 + public void StartAllClients(ProtocolClientConfig[] configs) { ThrowIfDisposed(); + if (configs == null || configs.Length == 0) + { + _logger.LogWarning("没有可用的协议客户端配置"); + return; + } + lock (_lock) { - _logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", _configFactory.ConfigCount); - var configs = _configFactory.GetAllConfigs(); - - if (configs.Length == 0) - { - _logger.LogWarning("没有可用的协议客户端配置"); - return; - } + _logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", configs.Length); var startedCount = 0; var failedCount = 0; diff --git a/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs b/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs new file mode 100644 index 0000000..8525d69 --- /dev/null +++ b/CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs @@ -0,0 +1,22 @@ +using CoreAgent.ProtocolClient.Models; + +namespace CoreAgent.ProtocolClient.Interfaces +{ + /// + /// 协议WebSocket客户端管理器接口 + /// 负责启动和停止所有协议客户端 + /// + public interface IProtocolWsClientManager : IDisposable + { + /// + /// 启动所有协议客户端 + /// + /// 协议客户端配置数组 + void StartAllClients(ProtocolClientConfig[] configs); + + /// + /// 停止所有协议客户端 + /// + void StopAllClients(); + } +} \ No newline at end of file diff --git a/modify.md b/modify.md index 341b80d..c649662 100644 --- a/modify.md +++ b/modify.md @@ -10,22 +10,28 @@ **修改内容**: -1. **添加第5.5步协议客户端配置创建** - - 在 `StartNetworkAsync` 方法的第5步(更新IP端点管理器)之后添加第5.5步 - - 直接创建 `ProtocolClientConfigFactory` 实例 - - 调用 `CreateFromEntities()` 方法创建协议客户端配置 - - 添加配置创建成功/失败的日志记录 - - **错误处理**:配置创建失败时立即返回失败结果,不继续执行后续步骤 - - **优化执行顺序**:将协议客户端配置创建提前到网络启动之前,确保数据可用性和错误隔离 - -2. **修复Logger类型问题** +1. **调整执行步骤顺序** + - 将原来的第5.5步改为第6步(创建协议客户端配置) + - 将WebSocket传输连接移到第7步(在网络配置启动之前) + - 重新编号后续步骤(8-11步) + - **优化执行顺序**:确保WebSocket连接在网络配置启动之前完成 + +2. **添加第7步WebSocket传输连接** + - 在 `StartNetworkAsync` 方法的第6步(创建协议客户端配置)之后添加第7步 + - 注入 `IWebSocketTransport` 依赖 + - 创建独立的 `StartWebSocketTransportAsync()` 方法处理连接逻辑 + - 返回 `bool` 值表示连接是否成功 + - 添加连接状态检查和错误处理 + - **严格检查**:WebSocket连接失败时立即返回失败结果,提示服务端可能未启动 + +3. **修复Logger类型问题** - 添加 `ILoggerFactory` 依赖注入到构造函数 - 使用 `_loggerFactory.CreateLogger()` 创建正确类型的Logger - 确保 `ProtocolClientConfigFactory` 获得正确的Logger实例 3. **具体实现**: ```csharp - // 5.5. 创建协议客户端配置 + // 6. 创建协议客户端配置 var protocolConfigFactory = new ProtocolClientConfigFactory(_loggerFactory.CreateLogger(), _context); var configCreated = protocolConfigFactory.CreateFromEntities(); if (configCreated) @@ -37,28 +43,327 @@ _logger.LogWarning("协议客户端配置创建失败"); return CellularNetworkOperationResult.Failure("协议客户端配置创建失败"); } + + // 7. 启动 WebSocket 传输连接 + var webSocketConnected = await StartWebSocketTransportAsync(); + if (!webSocketConnected) + { + _logger.LogError("WebSocket 传输连接启动失败,服务端可能未启动"); + return CellularNetworkOperationResult.Failure("WebSocket 传输连接启动失败,服务端可能未启动"); + } + _logger.LogInformation("WebSocket 传输连接启动成功"); ``` 4. **添加必要的依赖注入** - 添加 `ILoggerFactory loggerFactory` 参数到构造函数 + - 添加 `IWebSocketTransport webSocketTransport` 参数到构造函数 - 添加 `using CoreAgent.Infrastructure.Services.Network;` 以支持 `ProtocolClientConfigFactory` + - 添加 `using CoreAgent.WebSocketTransport.Interfaces;` 以支持 `IWebSocketTransport` 5. **设计优势**: - 在IP端点信息准备完成后立即创建协议客户端配置 - 不依赖网络启动结果,确保配置创建的独立性 - - 不依赖依赖注入,直接实例化使用 + - 在网络配置启动之前启动WebSocket传输连接 - 提供详细的日志记录便于调试 - 保持代码的简洁性和可维护性 - 正确处理Logger类型,避免类型不匹配问题 - 优化执行顺序,提高错误隔离能力 - 完善的错误处理机制,确保配置创建失败时及时停止 + - 严格检查机制,WebSocket连接失败时立即停止网络启动流程 + - 方法职责单一,WebSocket连接逻辑独立封装 **影响范围**: - 蜂窝网络启动流程 - 协议客户端配置管理 +- WebSocket传输服务集成 - 网络状态监控 - 依赖注入配置(需要更新服务注册) +### CellularNetworkService构造函数添加IProtocolLogObserver依赖 + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs` + +**修改内容**: + +1. **添加IProtocolLogObserver依赖注入** + - 在构造函数中添加 `IProtocolLogObserver protocolLogObserver` 参数 + - 添加私有字段 `_protocolLogObserver` 存储依赖 + - 添加空值检查和异常抛出 + +2. **添加必要的using语句** + - 添加 `using CoreAgent.ProtocolClient.ProtocolEngineCore;` 以支持 `IProtocolLogObserver` + +3. **具体实现**: + ```csharp + // 构造函数参数 + public CellularNetworkService( + // ... 其他参数 + IWebSocketTransport webSocketTransport, + IProtocolLogObserver protocolLogObserver) + + // 私有字段 + private readonly IProtocolLogObserver _protocolLogObserver; + + // 构造函数初始化 + _protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver)); + ``` + +4. **设计优势**: + - 为后续协议客户端管理提供必要的依赖 + - 保持依赖注入的一致性 + - 提供空值检查确保服务稳定性 + - 为协议日志观察者模式提供支持 + +**影响范围**: +- 蜂窝网络服务依赖注入配置 +- 协议客户端日志观察者集成 +- 服务注册配置更新 + +### StartNetworkAsync方法添加时间跟踪记录 + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs` + +**修改内容**: + +1. **添加整体时间跟踪** + - 在方法开始时记录开始时间 + - 在方法结束时计算总耗时并记录 + - 使用UTC时间确保时间一致性 + +2. **为每个步骤添加详细时间跟踪** + - 为11个步骤中的每个步骤添加开始和结束时间记录 + - 使用 `LogDebug` 级别记录每个步骤的耗时 + - 保持原有的 `LogInformation` 和 `LogError` 级别日志不变 + +3. **具体实现**: + ```csharp + // 方法开始时间跟踪 + var startTime = DateTime.UtcNow; + _logger.LogInformation("开始启动网络配置 {ConfigKey},开始时间: {StartTime}", key, startTime.ToString("yyyy-MM-dd HH:mm:ss.fff")); + + // 每个步骤的时间跟踪 + var stepXStart = DateTime.UtcNow; + _logger.LogDebug("步骤X开始:[步骤描述]"); + + // 步骤执行逻辑... + + var stepXDuration = (DateTime.UtcNow - stepXStart).TotalMilliseconds; + _logger.LogDebug("步骤X完成:[步骤描述],耗时: {Duration}ms", stepXDuration.ToString("F2")); + + // 方法结束时间跟踪 + var endTime = DateTime.UtcNow; + var duration = endTime - startTime; + _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status},总耗时: {Duration}ms", + key, state.CurrentStatus, duration.TotalMilliseconds.ToString("F2")); + ``` + +4. **设计优势**: + - **性能监控**:可以识别网络启动过程中的性能瓶颈 + - **调试支持**:详细的时间信息有助于问题定位和性能优化 + - **日志分级**:使用Debug级别避免生产环境日志过多 + - **时间精度**:使用毫秒级精度提供准确的性能数据 + - **UTC时间**:确保时间记录的一致性和准确性 + - **非侵入性**:不影响原有的业务逻辑和错误处理 + +5. **跟踪的步骤**: + - 步骤1:获取并验证网络配置 + - 步骤2:执行网络接口初始化命令 + - 步骤3:复制配置值到临时目录 + - 步骤4:获取并验证 IP 端点信息 + - 步骤5:更新 IP 端点管理器 + - 步骤6:创建协议客户端配置 + - 步骤7:启动 WebSocket 传输连接 + - 步骤8:启动网络配置 + - 步骤9:更新网络配置类型 + - 步骤10:检查网络端点连接状态 + - 步骤11:更新网络状态 + +**影响范围**: +- 网络启动性能监控 +- 调试和问题定位 +- 日志记录详细程度 +- 性能优化分析 + +### ProtocolWsClientManager方法参数优化 + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs` + +**修改内容**: + +1. **简化构造函数** + - 移除 `ProtocolClientConfig[] configs` 参数 + - 构造函数只保留必要的依赖:`ILogger`、`IProtocolLogObserver`、`ILoggerFactory` + - 移除私有字段 `_configs`,不再在构造函数中存储配置 + +2. **修改StartAllClients方法签名** + - 添加 `ProtocolClientConfig[] configs` 参数 + - 方法接收配置数组作为参数,而不是依赖构造函数中的配置 + - 添加参数验证,检查 `configs` 是否为 null 或空数组 + +3. **优化方法逻辑** + - 将配置验证移到方法开始处 + - 使用传入的 `configs` 参数替代私有字段 + - 保持原有的客户端创建和启动逻辑不变 + +4. **具体实现**: + ```csharp + // 构造函数简化 + public ProtocolWsClientManager( + ILogger logger, + IProtocolLogObserver protocolLogObserver, + ILoggerFactory loggerFactory) // 移除 configs 参数 + + // StartAllClients方法修改 + public void StartAllClients(ProtocolClientConfig[] configs) // 添加参数 + { + if (configs == null || configs.Length == 0) // 参数验证 + { + _logger.LogWarning("没有可用的协议客户端配置"); + return; + } + + // 使用传入的 configs 参数 + _logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", configs.Length); + foreach (var config in configs) // 遍历传入的配置 + ``` + +5. **设计优势**: + - **更灵活的使用方式**:可以在不同时间传入不同的配置 + - **减少内存占用**:不需要在构造函数中存储配置数组 + - **简化构造函数**:降低构造函数的复杂度 + - **更好的测试性**:可以更容易地测试不同的配置组合 + - **符合单一职责原则**:构造函数只负责初始化,方法负责执行具体操作 + +**影响范围**: +- 协议客户端管理器使用方式 +- 配置传递方式 +- 调用方代码适配 +- 测试用例更新 + +### ProtocolWsClientManager采用面向接口编程 + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.ProtocolClient/Interfaces/IProtocolWsClientManager.cs` (新建) +- `CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs` + +**修改内容**: + +1. **创建IProtocolWsClientManager接口** + - 在CoreAgent.ProtocolClient项目中定义接口契约 + - 继承 `IDisposable` 接口 + - 定义 `StartAllClients` 和 `StopAllClients` 方法 + - 使用 `ProtocolClientConfig[]` 作为参数类型 + +2. **修改ProtocolWsClientManager实现类** + - 实现 `IProtocolWsClientManager` 接口 + - 添加 `using CoreAgent.ProtocolClient.Interfaces;` 引用 + - 保持原有的实现逻辑不变 + +3. **具体实现**: + ```csharp + // 接口定义 + public interface IProtocolWsClientManager : IDisposable + { + void StartAllClients(ProtocolClientConfig[] configs); + void StopAllClients(); + } + + // 实现类 + public class ProtocolWsClientManager : IProtocolWsClientManager + { + // 原有实现保持不变 + } + ``` + +4. **设计优势**: + - **依赖倒置**:高层模块依赖抽象,不依赖具体实现 + - **易于测试**:可以轻松创建Mock实现进行单元测试 + - **松耦合**:降低组件间的耦合度 + - **可扩展性**:可以轻松添加新的实现类 + - **符合SOLID原则**:遵循依赖倒置原则和开闭原则 + - **便于依赖注入**:可以注册接口而不是具体实现 + +5. **接口设计原则**: + - **单一职责**:接口只定义协议客户端管理的核心功能 + - **简洁明了**:只包含必要的方法定义 + - **易于理解**:方法名称和参数清晰明确 + - **向后兼容**:保持与原有API的兼容性 + +**影响范围**: +- 依赖注入配置更新 +- 服务注册方式调整 +- 单元测试Mock创建 +- 调用方代码适配(使用接口类型) +- 项目引用关系调整(CoreAgent.ProtocolClient项目包含接口定义) + +### CellularNetworkService集成IProtocolWsClientManager + +**修改时间**: 2024年 +**修改文件**: +- `CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs` + +**修改内容**: + +1. **添加IProtocolWsClientManager依赖注入** + - 在构造函数中添加 `IProtocolWsClientManager protocolWsClientManager` 参数 + - 添加私有字段 `_protocolWsClientManager` 存储依赖 + - 添加空值检查和异常抛出 + +2. **StartNetworkAsync方法添加第12步** + - 在步骤11(更新网络状态)之后添加第12步 + - 调用 `protocolConfigFactory.GetAllConfigs()` 获取配置数组 + - 调用 `_protocolWsClientManager.StartAllClients(protocolConfigs)` 启动所有协议客户端 + - 添加时间跟踪和错误处理 + - 如果启动失败,立即返回失败结果 + +3. **StopAsync方法集成协议客户端停止** + - 在步骤4(禁用网络配置)之后添加步骤5(停止所有协议客户端) + - 调用 `_protocolWsClientManager.StopAllClients()` 停止所有协议客户端 + - 添加错误处理,但不中断停止流程 + - 重新编号后续步骤(6-9步) + +4. **修复StopWebSocketTransportAsync方法** + - 修正方法实现,使用 `CloseAsync()` 而不是 `DisconnectAsync()` + - 修正日志信息和返回值逻辑 + - 确保方法名称和实现一致 + +5. **具体实现**: + ```csharp + // 构造函数添加依赖 + public CellularNetworkService( + // ... 其他参数 + IProtocolWsClientManager protocolWsClientManager) + + // StartNetworkAsync第12步 + // 12. 启动所有协议客户端 + var protocolConfigs = protocolConfigFactory.GetAllConfigs(); + _protocolWsClientManager.StartAllClients(protocolConfigs); + + // StopAsync步骤5 + // 5. 停止所有协议客户端 + _protocolWsClientManager.StopAllClients(); + ``` + +6. **设计优势**: + - **完整的生命周期管理**:启动和停止时都正确处理协议客户端 + - **错误隔离**:启动失败时立即停止,停止失败时继续执行 + - **时间跟踪**:为协议客户端操作添加详细的时间记录 + - **依赖注入**:使用接口编程,便于测试和扩展 + - **日志完整**:提供详细的启动和停止日志记录 + +**影响范围**: +- 蜂窝网络服务依赖注入配置 +- 协议客户端生命周期管理 +- 网络启动和停止流程 +- 服务注册配置更新 + ### LogLayerHelp类名规范化 **修改时间**: 2024年