From 89926718f21e70ad3d85d9873af99349798652a9 Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sun, 15 Jun 2025 11:09:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/ICellularNetworkContext.cs | 12 +- .../Network/INetworkConfigCopier.cs | 2 +- .../Network/INetworkIPEndPointManager.cs | 2 +- .../Network/INetworkStatusMonitor.cs | 41 +++ .../Models/Network/NetworkConfigType.cs | 27 ++ .../Models/Network/NetworkIPEndPoints.cs | 2 +- .../NetworkInterfaceOperationResult.cs | 14 +- .../Models/Network/NetworkStatusModels.cs | 72 ++++ CoreAgent.Domain/Models/System/AppSettings.cs | 40 +++ .../Contexts/CellularNetworkContext.cs | 31 ++ .../CommandServiceExtensions.cs | 26 +- .../Network/CellularNetworkService.cs | 24 +- .../Services/Network/NetworkConfigCopier.cs | 4 +- .../Network/NetworkIPEndPointManager.cs | 2 +- .../Network/NetworkInterfaceManager.cs | 26 +- .../Services/Network/NetworkStatusMonitor.cs | 337 ++++++++++++++++++ 16 files changed, 629 insertions(+), 33 deletions(-) create mode 100644 CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs create mode 100644 CoreAgent.Domain/Models/Network/NetworkConfigType.cs create mode 100644 CoreAgent.Domain/Models/Network/NetworkStatusModels.cs create mode 100644 CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs diff --git a/CoreAgent.Domain/Interfaces/Network/ICellularNetworkContext.cs b/CoreAgent.Domain/Interfaces/Network/ICellularNetworkContext.cs index 05db761..f0ff768 100644 --- a/CoreAgent.Domain/Interfaces/Network/ICellularNetworkContext.cs +++ b/CoreAgent.Domain/Interfaces/Network/ICellularNetworkContext.cs @@ -25,6 +25,11 @@ public interface ICellularNetworkContext /// INetworkIPEndPointManager NetworkIPEndPointManager { get; } + /// + /// 当前网络配置类型 + /// + NetworkConfigType CurrentConfigType { get; } + #endregion #region 生命周期管理 @@ -65,6 +70,12 @@ public interface ICellularNetworkContext /// AppSettings GetAppSettings(); + /// + /// 更新网络配置类型 + /// + /// 网络配置类型 + void UpdateNetworkConfigType(NetworkConfigType configType); + #endregion #region 命令管理 @@ -91,6 +102,5 @@ public interface ICellularNetworkContext /// /// 网络状态 CellularNetworkState GetNetworkState(); - #endregion } \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs b/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs index d49200b..8e79e70 100644 --- a/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs +++ b/CoreAgent.Domain/Interfaces/Network/INetworkConfigCopier.cs @@ -22,5 +22,5 @@ public interface INetworkConfigCopier /// /// 网络配置 /// (EndPoints: IP 端点信息集合, HasAnyEndPoint: 是否成功获取到任何端点信息) - Task<(NetworkIPEndPoints EndPoints, bool HasAnyEndPoint)> GetComAddrInfoAsync(NetworkConfiguration networkConfig); + Task<(NetworkIPEndPointCollection EndPoints, bool HasAnyEndPoint)> GetComAddrInfoAsync(NetworkConfiguration networkConfig); } \ No newline at end of file diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkIPEndPointManager.cs b/CoreAgent.Domain/Interfaces/Network/INetworkIPEndPointManager.cs index 4514488..644a541 100644 --- a/CoreAgent.Domain/Interfaces/Network/INetworkIPEndPointManager.cs +++ b/CoreAgent.Domain/Interfaces/Network/INetworkIPEndPointManager.cs @@ -11,7 +11,7 @@ public interface INetworkIPEndPointManager /// 更新 IP 端点信息 /// /// IP 端点信息集合 - void UpdateEndPoints(NetworkIPEndPoints endPoints); + void UpdateEndPoints(NetworkIPEndPointCollection endPoints); /// /// 获取 RAN 端点信息 diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs b/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs new file mode 100644 index 0000000..cfb71dc --- /dev/null +++ b/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs @@ -0,0 +1,41 @@ +using CoreAgent.Domain.Models.Network; + +namespace CoreAgent.Domain.Interfaces.Network; + +/// +/// 网络状态监控接口 +/// +public interface INetworkStatusMonitor +{ + /// + /// 检查所有网络端点的状态 + /// + /// 网络端点信息 + /// 网络配置类型 + /// 检查结果 + public Task CheckAllEndPointsStatusAsync( + NetworkIPEndPointCollection endPoints, + NetworkConfigType configType, + int? timeoutSeconds = null); + + /// + /// 检查 RAN 端点状态 + /// + /// RAN 端点信息 + /// RAN 端点状态 + Task CheckRanStatusAsync(RanIPEndPoint ranEndPoint); + + /// + /// 检查 IMS 端点状态 + /// + /// IMS 端点信息列表 + /// IMS 端点状态列表 + Task> CheckImsStatusAsync(List imsEndPoints); + + /// + /// 检查 CN 端点状态 + /// + /// CN 端点信息列表 + /// CN 端点状态列表 + Task> CheckCnStatusAsync(List cnEndPoints); +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Network/NetworkConfigType.cs b/CoreAgent.Domain/Models/Network/NetworkConfigType.cs new file mode 100644 index 0000000..e4e48c7 --- /dev/null +++ b/CoreAgent.Domain/Models/Network/NetworkConfigType.cs @@ -0,0 +1,27 @@ +namespace CoreAgent.Domain.Models.Network; + +/// +/// 网络配置类型 +/// +public enum NetworkConfigType +{ + /// + /// 无配置 + /// + None = 0, + + /// + /// 同时包含RAG和Core配置 + /// + BothRagAndCore, + + /// + /// 仅包含RAG配置 + /// + RagOnly, + + /// + /// 仅包含Core配置 + /// + CoreOnly +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Network/NetworkIPEndPoints.cs b/CoreAgent.Domain/Models/Network/NetworkIPEndPoints.cs index b5545de..5e57937 100644 --- a/CoreAgent.Domain/Models/Network/NetworkIPEndPoints.cs +++ b/CoreAgent.Domain/Models/Network/NetworkIPEndPoints.cs @@ -3,7 +3,7 @@ namespace CoreAgent.Domain.Models.Network; /// /// 网络 IP 端点集合 /// -public class NetworkIPEndPoints +public class NetworkIPEndPointCollection { /// /// IMS 网络 IP 端点列表 diff --git a/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs b/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs index ba4aeb2..a902c23 100644 --- a/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs +++ b/CoreAgent.Domain/Models/Network/NetworkInterfaceOperationResult.cs @@ -15,20 +15,28 @@ public class NetworkInterfaceOperationResult /// public string ErrorMessage { get; } - private NetworkInterfaceOperationResult(bool isSuccess, string errorMessage = null) + /// + /// 网络配置类型 + /// + public NetworkConfigType ConfigType { get; } + + private NetworkInterfaceOperationResult(bool isSuccess, string errorMessage = null, NetworkConfigType configType = NetworkConfigType.None) { IsSuccess = isSuccess; ErrorMessage = errorMessage; + ConfigType = configType; } /// /// 创建成功结果 /// - public static NetworkInterfaceOperationResult Success() => new(true); + /// 网络配置类型 + public static NetworkInterfaceOperationResult Success(NetworkConfigType configType = NetworkConfigType.None) => new(true, null, configType); /// /// 创建失败结果 /// /// 错误信息 - public static NetworkInterfaceOperationResult Failure(string errorMessage) => new(false, errorMessage); + /// 网络配置类型 + public static NetworkInterfaceOperationResult Failure(string errorMessage, NetworkConfigType configType = NetworkConfigType.None) => new(false, errorMessage, configType); } \ No newline at end of file diff --git a/CoreAgent.Domain/Models/Network/NetworkStatusModels.cs b/CoreAgent.Domain/Models/Network/NetworkStatusModels.cs new file mode 100644 index 0000000..e127d6c --- /dev/null +++ b/CoreAgent.Domain/Models/Network/NetworkStatusModels.cs @@ -0,0 +1,72 @@ +using CoreAgent.Domain.Models.Network; + +namespace CoreAgent.Domain.Models.Network; + +/// +/// 端点状态检查结果 +/// +public class EndPointStatusResult +{ + /// + /// 通信地址 + /// + public string ComAddr { get; set; } + + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } + + /// + /// 错误信息 + /// + public string ErrorMessage { get; set; } + + /// + /// 网络协议类型 + /// + public NetworkProtocolType NetworkProtocolType { get; set; } +} + +/// +/// 网络状态检查结果 +/// +public class NetworkStatusCheckResult +{ + + /// + /// 是否成功 + /// + public bool IsSuccess { get; set; } + + /// + /// 错误信息 + /// + public string[] ErrorMessage { get; set; } +} + +/// +/// 网络协议类型 +/// +public enum NetworkProtocolType +{ + /// + /// 未指定 + /// + None = 0, + + /// + /// RAN 协议 + /// + Ran = 1, + + /// + /// IMS 协议 + /// + Ims = 2, + + /// + /// CN 协议 + /// + Cn = 3 +} \ No newline at end of file diff --git a/CoreAgent.Domain/Models/System/AppSettings.cs b/CoreAgent.Domain/Models/System/AppSettings.cs index 43ac941..a7e6e70 100644 --- a/CoreAgent.Domain/Models/System/AppSettings.cs +++ b/CoreAgent.Domain/Models/System/AppSettings.cs @@ -24,4 +24,44 @@ public class AppSettings /// WebSocket JavaScript文件路径 /// public string WebSocketJsPath { get; set; } = "/root/enb/doc/ws.js"; + + /// + /// WebSocket 命令配置 + /// + public WebSocketCommandSettings WebSocketCommands { get; set; } = new(); + + /// + /// 网络状态检查超时时间(秒) + /// + public int NetworkStatusCheckTimeout { get; set; } = 30; +} + +/// +/// WebSocket 命令配置 +/// +public class WebSocketCommandSettings +{ + /// + /// 状态检查命令 + /// + public WebSocketCommand Stats { get; set; } = new() + { + Message = "stats" + }; +} + +/// +/// WebSocket 命令 +/// +public class WebSocketCommand +{ + /// + /// 消息类型 + /// + public string Message { get; set; } = string.Empty; + + /// + /// 转换为 JSON 字符串 + /// + public string ToJson() => $"{{\"message\":\"{Message}\"}}"; } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Contexts/CellularNetworkContext.cs b/CoreAgent.Infrastructure/Contexts/CellularNetworkContext.cs index b799e53..ef8e3c6 100644 --- a/CoreAgent.Infrastructure/Contexts/CellularNetworkContext.cs +++ b/CoreAgent.Infrastructure/Contexts/CellularNetworkContext.cs @@ -20,6 +20,7 @@ public class CellularNetworkContext : ICellularNetworkContext, IDisposable private bool _isDisposed; private bool _isInitialized; private readonly INetworkIPEndPointManager _networkIPEndPointManager; + private NetworkConfigType _currentConfigType; /// /// 获取取消令牌源 @@ -36,6 +37,11 @@ public class CellularNetworkContext : ICellularNetworkContext, IDisposable /// public INetworkIPEndPointManager NetworkIPEndPointManager => _networkIPEndPointManager; + /// + /// 当前网络配置类型 + /// + public NetworkConfigType CurrentConfigType => _currentConfigType; + public CellularNetworkContext( IOptions networkCommandConfig, IOptions appSettings, @@ -47,6 +53,7 @@ public class CellularNetworkContext : ICellularNetworkContext, IDisposable _networkCommandConfig = networkCommandConfig?.Value ?? throw new ArgumentNullException(nameof(networkCommandConfig)); _appSettings = appSettings?.Value ?? throw new ArgumentNullException(nameof(appSettings)); _networkIPEndPointManager = networkIPEndPointManager ?? throw new ArgumentNullException(nameof(networkIPEndPointManager)); + _currentConfigType = NetworkConfigType.None; } /// @@ -75,10 +82,33 @@ public class CellularNetworkContext : ICellularNetworkContext, IDisposable _networkIPEndPointManager.Clear(); _neConfigKey = neConfigKey; _networkState = new CellularNetworkState(_neConfigKey); + _currentConfigType = NetworkConfigType.None; _isInitialized = true; } } + /// + /// 更新网络配置类型 + /// + /// 网络配置类型 + public void UpdateNetworkConfigType(NetworkConfigType configType) + { + if (_isDisposed) + { + throw new ObjectDisposedException(nameof(CellularNetworkContext)); + } + + if (!_isInitialized) + { + throw new InvalidOperationException("上下文未初始化"); + } + + lock (_lock) + { + _currentConfigType = configType; + } + } + /// /// 获取网络命令配置 /// @@ -192,6 +222,7 @@ public class CellularNetworkContext : ICellularNetworkContext, IDisposable _isInitialized = false; _networkState = new CellularNetworkState(string.Empty); _networkIPEndPointManager.Clear(); + _currentConfigType = NetworkConfigType.None; } } diff --git a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs index 9e68ce1..b1d2070 100644 --- a/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs +++ b/CoreAgent.Infrastructure/Extensions/ServiceCollection/CommandServiceExtensions.cs @@ -1,4 +1,3 @@ - using CoreAgent.Domain.Interfaces; using CoreAgent.Domain.Interfaces.Network; using CoreAgent.Domain.Interfaces.System.Command; @@ -17,30 +16,43 @@ namespace CoreAgent.Infrastructure.Extensions.ServiceCollection; public static class CommandServiceExtensions { /// - /// 添加命令策略服务 + /// 添加命令相关的自定义服务 /// + /// + /// 此方法注册以下服务: + /// 1. 网络IP端点管理器(单例) + /// 2. 蜂窝网络上下文(单例) + /// 3. 系统命令执行器工厂(单例) + /// 4. 系统命令执行器(瞬时) + /// 5. 网络配置仓储(作用域) + /// 6. 网络配置服务(作用域) + /// 7. 网络配置复制器(作用域) + /// 8. 网络接口管理器(作用域) + /// 9. 网络状态监控器(作用域) + /// 10. 蜂窝网络服务(作用域) + /// /// 服务集合 /// 服务集合 public static IServiceCollection AddCommandCustomService(this IServiceCollection services) { + // 注册单例服务 services.AddSingleton(); services.AddSingleton(); - // 注册命令执行器工厂 services.AddSingleton(); - // 注册命令执行器 + // 注册命令执行器(瞬时) services.AddTransient(sp => { var factory = sp.GetRequiredService(); return factory.CreateExecutor(); }); - // 注册网络配置器 + + // 注册作用域服务 services.AddScoped(); - // 注册网络配置器 services.AddScoped(); services.AddScoped(); services.AddScoped(); - // 注册网络服务 + services.AddScoped(); services.AddScoped(); return services; diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs index 75352ea..06f7d60 100644 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs +++ b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs @@ -22,6 +22,7 @@ public class CellularNetworkService : ICellularNetworkService private readonly ICellularNetworkContext _context; private readonly INetworkConfigCopier _configCopier; private readonly INetworkInterfaceManager _interfaceManager; + private readonly INetworkStatusMonitor _statusMonitor; private static readonly SemaphoreSlim _startLock = new(1, 1); private const int LockTimeoutSeconds = 60; @@ -32,7 +33,8 @@ public class CellularNetworkService : ICellularNetworkService INetworkConfigurationService configService, ICellularNetworkContext context, INetworkConfigCopier configCopier, - INetworkInterfaceManager interfaceManager) + INetworkInterfaceManager interfaceManager, + INetworkStatusMonitor statusMonitor) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor)); @@ -40,6 +42,7 @@ public class CellularNetworkService : ICellularNetworkService _context = context ?? throw new ArgumentNullException(nameof(context)); _configCopier = configCopier ?? throw new ArgumentNullException(nameof(configCopier)); _interfaceManager = interfaceManager ?? throw new ArgumentNullException(nameof(interfaceManager)); + _statusMonitor = statusMonitor; } /// @@ -240,10 +243,25 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure(message); } - // 7. 更新状态 + // 7. 更新网络配置类型 + _context.UpdateNetworkConfigType(enableResult.ConfigType); + _logger.LogInformation("更新网络配置类型: {ConfigType}", enableResult.ConfigType); + + // 8. 检查所有网络端点的连接状态 + _logger.LogInformation("开始检查所有网络端点的连接状态"); + var statusCheckResult = await _statusMonitor.CheckAllEndPointsStatusAsync(endPoints, enableResult.ConfigType); + if (!statusCheckResult.IsSuccess) + { + var errorMessage = string.Join("; ", statusCheckResult.ErrorMessage); + _logger.LogWarning("网络端点状态检查未通过: {ErrorMessage}", errorMessage); + return CellularNetworkOperationResult.Failure($"网络端点状态检查失败: {errorMessage}"); + } + _logger.LogInformation("网络端点状态检查完成,所有端点状态正常"); + + // 9. 更新状态 var state = _context.GetNetworkState(); state.MarkAsStarted(); - _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功", key); + _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status}", key, state.CurrentStatus); return CellularNetworkOperationResult.Success(state.CurrentStatus); } } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs b/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs index 9cb24ab..0224348 100644 --- a/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs +++ b/CoreAgent.Infrastructure/Services/Network/NetworkConfigCopier.cs @@ -205,9 +205,9 @@ public class NetworkConfigCopier : INetworkConfigCopier /// /// 网络配置 /// (EndPoints: IP 端点信息集合, HasAnyEndPoint: 是否成功获取到任何端点信息) - public async Task<(NetworkIPEndPoints EndPoints, bool HasAnyEndPoint)> GetComAddrInfoAsync(NetworkConfiguration networkConfig) + public async Task<(NetworkIPEndPointCollection EndPoints, bool HasAnyEndPoint)> GetComAddrInfoAsync(NetworkConfiguration networkConfig) { - var endPoints = new NetworkIPEndPoints(); + var endPoints = new NetworkIPEndPointCollection(); bool hasAnyEndPoint = false; try diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkIPEndPointManager.cs b/CoreAgent.Infrastructure/Services/Network/NetworkIPEndPointManager.cs index aaf3fe4..1c4ae80 100644 --- a/CoreAgent.Infrastructure/Services/Network/NetworkIPEndPointManager.cs +++ b/CoreAgent.Infrastructure/Services/Network/NetworkIPEndPointManager.cs @@ -24,7 +24,7 @@ public class NetworkIPEndPointManager : INetworkIPEndPointManager /// 更新 IP 端点信息 /// /// IP 端点信息集合 - public void UpdateEndPoints(NetworkIPEndPoints endPoints) + public void UpdateEndPoints(NetworkIPEndPointCollection endPoints) { if (endPoints == null) { diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs b/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs index e99017b..b24658c 100644 --- a/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs +++ b/CoreAgent.Infrastructure/Services/Network/NetworkInterfaceManager.cs @@ -70,14 +70,14 @@ public class NetworkInterfaceManager : INetworkInterfaceManager // 验证配置 if (!ValidateConfig(networkConfig)) { - return NetworkInterfaceOperationResult.Failure("网络配置验证失败"); + return NetworkInterfaceOperationResult.Failure("网络配置验证失败", NetworkConfigType.None); } var commands = _context.GetNetworkCommandConfig(); var startCommand = commands.NetworkCommands.FirstOrDefault(s => s.Type == NetworkCommandType.NetworkOperation); if (startCommand == null) { - return NetworkInterfaceOperationResult.Failure("未找到启动命令配置"); + return NetworkInterfaceOperationResult.Failure("未找到启动命令配置", NetworkConfigType.None); } // 根据配置类型执行不同的启动命令 @@ -94,12 +94,12 @@ public class NetworkInterfaceManager : INetworkInterfaceManager return await ExecuteCoreOnlyStartCommandsAsync(startCommand, networkConfig); } - return NetworkInterfaceOperationResult.Failure("无有效配置,跳过启动"); + return NetworkInterfaceOperationResult.Failure("无有效配置,跳过启动", NetworkConfigType.None); } catch (Exception ex) { _logger.LogError(ex, "启动网络接口失败"); - return NetworkInterfaceOperationResult.Failure($"启动网络接口失败: {ex.Message}"); + return NetworkInterfaceOperationResult.Failure($"启动网络接口失败: {ex.Message}", NetworkConfigType.None); } } @@ -226,8 +226,8 @@ public class NetworkInterfaceManager : INetworkInterfaceManager _logger.LogInformation("执行RAG配置启动命令: {Command}", fullCommand); var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, new CancellationTokenSource()); return result.IsSuccess - ? NetworkInterfaceOperationResult.Success() - : NetworkInterfaceOperationResult.Failure($"执行RAG配置启动命令失败: {result.Error}"); + ? NetworkInterfaceOperationResult.Success(NetworkConfigType.RagOnly) + : NetworkInterfaceOperationResult.Failure($"执行RAG配置启动命令失败: {result.Error}", NetworkConfigType.RagOnly); } private async Task ExecuteCoreOnlyStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) @@ -251,9 +251,9 @@ public class NetworkInterfaceManager : INetworkInterfaceManager var secondaryResults = await Task.WhenAll(secondaryTasks); if (secondaryResults.Any(r => !r.IsSuccess)) { - return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败"); + return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败", NetworkConfigType.CoreOnly); } - return NetworkInterfaceOperationResult.Success(); + return NetworkInterfaceOperationResult.Success(NetworkConfigType.CoreOnly); } private async Task ExecuteSingleConfigStartCommandAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) @@ -265,8 +265,8 @@ public class NetworkInterfaceManager : INetworkInterfaceManager _logger.LogInformation("执行单配置启动命令: {Command}", fullCommand); var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource); return result.IsSuccess - ? NetworkInterfaceOperationResult.Success() - : NetworkInterfaceOperationResult.Failure($"执行单配置启动命令失败: {result.Error}"); + ? NetworkInterfaceOperationResult.Success(NetworkConfigType.BothRagAndCore) + : NetworkInterfaceOperationResult.Failure($"执行单配置启动命令失败: {result.Error}", NetworkConfigType.BothRagAndCore); } private async Task ExecuteMultiConfigStartCommandsAsync(CommandTemplateConfig startCommand, NetworkConfiguration networkConfig) @@ -289,7 +289,7 @@ public class NetworkInterfaceManager : INetworkInterfaceManager var secondaryResults = await Task.WhenAll(secondaryTasks); if (secondaryResults.Any(r => !r.IsSuccess)) { - return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败"); + return NetworkInterfaceOperationResult.Failure("部分次要配置命令执行失败", NetworkConfigType.BothRagAndCore); } // 执行主配置命令 @@ -303,10 +303,10 @@ public class NetworkInterfaceManager : INetworkInterfaceManager var result = await _commandExecutor.ExecuteCommandAsync(fullCommand, _context.TokenSource); if (!result.IsSuccess) { - return NetworkInterfaceOperationResult.Failure($"主配置命令执行失败: {result.Error}"); + return NetworkInterfaceOperationResult.Failure($"主配置命令执行失败: {result.Error}", NetworkConfigType.BothRagAndCore); } } - return NetworkInterfaceOperationResult.Success(); + return NetworkInterfaceOperationResult.Success(NetworkConfigType.BothRagAndCore); } } \ No newline at end of file diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs b/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs new file mode 100644 index 0000000..b00bbda --- /dev/null +++ b/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs @@ -0,0 +1,337 @@ +using CoreAgent.Domain.Helpers; +using CoreAgent.Domain.Interfaces.Network; +using CoreAgent.Domain.Interfaces.System.Command; +using CoreAgent.Domain.Models.Network; +using CoreAgent.Domain.Models.System; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System.Text.Json; + +namespace CoreAgent.Infrastructure.Services.Network; + +/// +/// 网络状态监控管理类 +/// +public class NetworkStatusMonitor : INetworkStatusMonitor +{ + private readonly ILogger _logger; + private readonly ISystemCommandExecutor _commandExecutor; + private readonly AppSettings _appSettings; + + public NetworkStatusMonitor( + ILogger logger, + ISystemCommandExecutor commandExecutor, + IOptions appSettings) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor)); + _appSettings = appSettings?.Value ?? throw new ArgumentNullException(nameof(appSettings)); + } + + /// + /// 检查所有网络端点的状态 + /// + /// 网络端点信息 + /// 网络配置类型 + /// 超时时间(秒),默认30秒 + /// 检查结果 + public async Task CheckAllEndPointsStatusAsync( + NetworkIPEndPointCollection endPoints, + NetworkConfigType configType, + int? timeoutSeconds = null) + { + var result = new NetworkStatusCheckResult(); + var startTime = DateTime.Now; + var timeout = TimeSpan.FromSeconds(timeoutSeconds ?? _appSettings.NetworkStatusCheckTimeout); + + try + { + _logger.LogInformation("开始检查网络端点状态,配置类型: {ConfigType}, 超时时间: {TimeoutSeconds}秒", + configType, timeout.TotalSeconds); + + // 先执行一次检查 + var checkResults = await CheckEndPointsByConfigTypeAsync(endPoints, configType); + result.IsSuccess = checkResults.All(r => r.IsSuccess); + + // 如果检查失败,进入重试循环 + while (!result.IsSuccess && DateTime.Now - startTime < timeout) + { + var failedEndpoints = checkResults.Where(r => !r.IsSuccess) + .Select(r => $"{r.ComAddr}: {r.ErrorMessage}"); + var errorMessage = string.Join("; ", failedEndpoints); + _logger.LogWarning("网络端点状态检查未通过,失败端点: {FailedEndpoints},将在1秒后重试,已耗时: {ElapsedTime}秒", + errorMessage, (DateTime.Now - startTime).TotalSeconds); + + await Task.Delay(1000); // 等待1秒后重试 + + // 重试检查 + checkResults = await CheckEndPointsByConfigTypeAsync(endPoints, configType); + result.IsSuccess = checkResults.All(r => r.IsSuccess); + } + + if (!result.IsSuccess) + { + result.ErrorMessage = new string[] { $"检查超时,已超过{timeout.TotalSeconds}秒" }; + _logger.LogWarning("网络端点状态检查超时,配置类型: {ConfigType}", configType); + } + else + { + _logger.LogInformation("网络端点状态检查成功,配置类型: {ConfigType}, 耗时: {ElapsedTime}秒", + configType, (DateTime.Now - startTime).TotalSeconds); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "检查网络端点状态时发生错误,配置类型: {ConfigType}", configType); + result.IsSuccess = false; + result.ErrorMessage = new string[] { $"检查过程发生异常: {ex.Message}" }; + } + + return result; + } + + /// + /// 根据配置类型检查相应的端点状态 + /// + /// 所有端点的检查结果 + private async Task CheckEndPointsByConfigTypeAsync(NetworkIPEndPointCollection endPoints, NetworkConfigType configType) + { + var results = new List(); + + switch (configType) + { + case NetworkConfigType.BothRagAndCore: + var ragResult = await CheckRagEndPointsAsync(endPoints); + results.Add(ragResult); + var coreResult = await CheckCoreEndPointsAsync(endPoints); + results.Add(coreResult); + break; + + case NetworkConfigType.RagOnly: + var ragOnlyResult = await CheckRagEndPointsAsync(endPoints); + results.Add(ragOnlyResult); + break; + + case NetworkConfigType.CoreOnly: + var coreOnlyResult = await CheckCoreEndPointsAsync(endPoints); + results.Add(coreOnlyResult); + break; + + case NetworkConfigType.None: + default: + _logger.LogWarning("无需检查网络端点状态,配置类型: {ConfigType}", configType); + break; + } + + return results.ToArray(); + } + + /// + /// 检查 RAG 相关端点状态 + /// + /// 检查结果 + private async Task CheckRagEndPointsAsync(NetworkIPEndPointCollection endPoints) + { + var result = new EndPointStatusResult(); + + if (endPoints.RanEndPoint == null) + { + result.IsSuccess = true; + return result; + } + + result.ComAddr = endPoints.RanEndPoint.ComAddr; + var ranResult = await CheckRanStatusAsync(endPoints.RanEndPoint); + _logger.LogInformation("RAN 端点状态检查: {ComAddr}, 结果: {IsSuccess}", + ranResult.ComAddr, ranResult.IsSuccess); + + result.IsSuccess = ranResult.IsSuccess; + result.ErrorMessage = ranResult.ErrorMessage; + return result; + } + + /// + /// 检查 Core 相关端点状态 + /// + /// 检查结果 + private async Task CheckCoreEndPointsAsync(NetworkIPEndPointCollection endPoints) + { + var result = new EndPointStatusResult { IsSuccess = true }; + var errorMessages = new List(); + + // 检查 IMS 端点 + if (endPoints.ImsEndPoints != null && endPoints.ImsEndPoints.Any()) + { + var imsResults = await CheckImsStatusAsync(endPoints.ImsEndPoints); + foreach (var imsResult in imsResults) + { + _logger.LogInformation("IMS 端点状态检查: {ComAddr}, 结果: {IsSuccess}", + imsResult.ComAddr, imsResult.IsSuccess); + + if (!imsResult.IsSuccess) + { + result.IsSuccess = false; + errorMessages.Add($"IMS端点 {imsResult.ComAddr}: {imsResult.ErrorMessage}"); + } + } + } + + // 检查 CN 端点 + if (endPoints.CnEndPoints != null && endPoints.CnEndPoints.Any()) + { + var cnResults = await CheckCnStatusAsync(endPoints.CnEndPoints); + foreach (var cnResult in cnResults) + { + _logger.LogInformation("CN 端点状态检查: {ComAddr}, 结果: {IsSuccess}", + cnResult.ComAddr, cnResult.IsSuccess); + + if (!cnResult.IsSuccess) + { + result.IsSuccess = false; + errorMessages.Add($"CN端点 {cnResult.ComAddr}: {cnResult.ErrorMessage}"); + } + } + } + + if (!result.IsSuccess) + { + result.ErrorMessage = string.Join("; ", errorMessages); + } + + return result; + } + + /// + /// 检查 RAN 端点状态 + /// + /// RAN 端点信息 + /// RAN 端点状态 + public async Task CheckRanStatusAsync(RanIPEndPoint ranEndPoint) + { + var result = new EndPointStatusResult(); + + if (ranEndPoint == null) + { + result.IsSuccess = false; + result.ErrorMessage = "RAN 端点未配置"; + _logger.LogWarning(result.ErrorMessage); + return result; + } + + result.ComAddr = ranEndPoint.ComAddr; + try + { + await CheckEndPointStatusAsync(ranEndPoint.ComAddr, "RAN"); + result.IsSuccess = true; + } + catch (Exception ex) + { + result.IsSuccess = false; + result.ErrorMessage = ex.Message; + _logger.LogError(ex, "检查 RAN 端点状态失败"); + } + + return result; + } + + /// + /// 检查 IMS 端点状态 + /// + /// IMS 端点信息列表 + /// IMS 端点状态列表 + public async Task> CheckImsStatusAsync(List imsEndPoints) + { + var result = new List(); + + if (imsEndPoints == null || !imsEndPoints.Any()) + { + return result; + } + + foreach (var imsEndPoint in imsEndPoints) + { + var statusResult = new EndPointStatusResult + { + ComAddr = imsEndPoint.ComAddr + }; + + try + { + await CheckEndPointStatusAsync(imsEndPoint.ComAddr, "IMS"); + statusResult.IsSuccess = true; + } + catch (Exception ex) + { + statusResult.IsSuccess = false; + statusResult.ErrorMessage = ex.Message; + _logger.LogError(ex, "检查 IMS 端点 {ComAddr} 状态失败", imsEndPoint.ComAddr); + } + + result.Add(statusResult); + } + + return result; + } + + /// + /// 检查 CN 端点状态 + /// + /// CN 端点信息列表 + /// CN 端点状态列表 + public async Task> CheckCnStatusAsync(List cnEndPoints) + { + var result = new List(); + + if (cnEndPoints == null || !cnEndPoints.Any()) + { + return result; + } + + foreach (var cnEndPoint in cnEndPoints) + { + var statusResult = new EndPointStatusResult + { + ComAddr = cnEndPoint.ComAddr + }; + + try + { + await CheckEndPointStatusAsync(cnEndPoint.ComAddr, "CN"); + statusResult.IsSuccess = true; + } + catch (Exception ex) + { + statusResult.IsSuccess = false; + statusResult.ErrorMessage = ex.Message; + _logger.LogError(ex, "检查 CN 端点 {ComAddr} 状态失败", cnEndPoint.ComAddr); + } + + result.Add(statusResult); + } + + return result; + } + + /// + /// 检查单个端点的状态 + /// + /// 通信地址 + /// 端点类型 + private async Task<(bool isSuccess, string data)> CheckEndPointStatusAsync(string comAddr, string endPointType) + { + var command = $"{_appSettings.WebSocketJsPath} {comAddr} '{_appSettings.WebSocketCommands.Stats.ToJson()}'"; + var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); + + if (result.IsSuccess) + { + _logger.LogInformation("{EndPointType} 端点 {ComAddr} 状态检查成功", endPointType, comAddr); + return (result.IsSuccess, result.Output.ParseWsResultLogs()); + } + else + { + var error = $"检查失败: {result.Error}"; + _logger.LogWarning("{EndPointType} 端点 {ComAddr} 状态检查失败: {Error}", endPointType, comAddr, result.Error); + return (result.IsSuccess, result.Output.ParseWsResultLogs()); + } + } +} \ No newline at end of file