From 7f9821964b77206256e9794ef19badfddd51017a Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sun, 15 Jun 2025 12:34:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BD=91=E7=BB=9C=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=9B=91=E6=8E=A7=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/INetworkStatusMonitor.cs | 7 ++ CoreAgent.Domain/Models/System/AppSettings.cs | 5 ++ .../Network/CellularNetworkService.cs | 61 +++++++++++---- .../Services/Network/NetworkStatusMonitor.cs | 76 +++++++++++++++---- 4 files changed, 119 insertions(+), 30 deletions(-) diff --git a/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs b/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs index cfb71dc..8e512ac 100644 --- a/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs +++ b/CoreAgent.Domain/Interfaces/Network/INetworkStatusMonitor.cs @@ -38,4 +38,11 @@ public interface INetworkStatusMonitor /// CN 端点信息列表 /// CN 端点状态列表 Task> CheckCnStatusAsync(List cnEndPoints); + + /// + /// 检查 RAN 端点退出状态 + /// + /// RAN 端点信息 + /// 是否成功退出 + Task CheckRanQuitAsync(RanIPEndPoint ranEndPoint); } \ No newline at end of file diff --git a/CoreAgent.Domain/Models/System/AppSettings.cs b/CoreAgent.Domain/Models/System/AppSettings.cs index a7e6e70..dbf39d5 100644 --- a/CoreAgent.Domain/Models/System/AppSettings.cs +++ b/CoreAgent.Domain/Models/System/AppSettings.cs @@ -48,6 +48,11 @@ public class WebSocketCommandSettings { Message = "stats" }; + + public WebSocketCommand Quit { get; set; } = new() + { + Message = "quit" + }; } /// diff --git a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs index 06f7d60..f708f9b 100644 --- a/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs +++ b/CoreAgent.Infrastructure/Services/Network/CellularNetworkService.cs @@ -153,50 +153,81 @@ public class CellularNetworkService : ICellularNetworkService } } - public async Task StopAsync(string Key) + /// + /// 停止蜂窝网络 + /// + /// 网络配置键 + /// 停止操作的结果 + public async Task StopAsync(string key) { string neConfigKey = _context.GetNeConfigKey(); try { - // 1. 检查网络状态 + // 1. 检查当前网络状态 var state = _context.GetNetworkState(); if (state.CurrentStatus == NetworkStatus.Disconnected || state.CurrentStatus == NetworkStatus.Unknown) { _logger.LogWarning("蜂窝网络已经处于断开或未知状态,无需停止"); - _context.Reset(); // 即使不需要停止,也重置状态 + _context.Reset(); // 重置上下文状态 return CellularNetworkOperationResult.Success(NetworkStatus.Disconnected); } - // 2. 执行初始化命令 + // 2. 检查 RAN 退出状态(仅当配置类型为 BothRagAndCore 时) + if (_context.CurrentConfigType == NetworkConfigType.BothRagAndCore) + { + var isRanQuit = await _statusMonitor.CheckRanQuitAsync(_context.NetworkIPEndPointManager.GetRanEndPoint()); + if (!isRanQuit) + { + _logger.LogWarning("RAN 退出状态检查失败"); + return CellularNetworkOperationResult.Failure("RAN 退出状态检查失败"); + } + } + + // 3. 执行网络接口初始化命令 var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync(); if (!initResult.IsSuccess) { _logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage); } - // 4. 停止网络配置 + + // 4. 禁用网络配置 var disableResult = await _interfaceManager.DisableAsync(neConfigKey); if (!disableResult.IsSuccess) { return CellularNetworkOperationResult.Failure(disableResult.ErrorMessage); } - // 5. 更新状态 - _logger.LogInformation($"蜂窝网络配置 {neConfigKey} 停止成功"); + // 5. 收集所有网络端点信息 + var endPoints = new NetworkIPEndPointCollection + { + RanEndPoint = _context.NetworkIPEndPointManager.GetRanEndPoint(), + ImsEndPoints = _context.NetworkIPEndPointManager.GetImsEndPoints(), + CnEndPoints = _context.NetworkIPEndPointManager.GetCnEndPoints() + }; + + // 6. 检查网络端点连接状态 + _logger.LogInformation("开始检查所有网络端点的连接状态"); + var statusCheckResult = await _statusMonitor.CheckAllEndPointsStatusAsync(endPoints, _context.CurrentConfigType); + if (statusCheckResult.IsSuccess) + { + _logger.LogWarning("网络端点仍然处于连接状态,停止操作失败"); + return CellularNetworkOperationResult.Failure("网络端点仍然处于连接状态,停止操作失败"); + } - // 6. 重置上下文 + // 7. 重置上下文并返回成功结果 _context.Reset(); return CellularNetworkOperationResult.Success(NetworkStatus.Disconnected); } catch (Exception ex) { - _logger.LogError(ex, $"停止蜂窝网络配置 {neConfigKey} 失败"); + _logger.LogError(ex, "停止蜂窝网络配置 {ConfigKey} 失败", neConfigKey); return CellularNetworkOperationResult.Failure($"停止蜂窝网络失败: {ex.Message}"); } } private async Task StartNetworkAsync(string key) { - // 1. 获取并验证配置 + // 1. 获取并验证网络配置 var config = await _configService.GetByConfigKeyAsync(key); if (config == null) { @@ -205,14 +236,14 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure(message); } - // 2. 执行初始化命令 + // 2. 执行网络接口初始化命令 var initResult = await _interfaceManager.ExecuteInitializeCommandsAsync(true); if (!initResult.IsSuccess) { _logger.LogWarning("执行初始化命令失败: {ErrorMessage}", initResult.ErrorMessage); } - // 3. 复制配置值到临时目录并更新配置路径 + // 3. 复制配置值到临时目录 var copyResult = await _configCopier.CopyConfigValuesToTempAsync(config, _context.GetAppSettings()); if (!copyResult.IsSuccess) { @@ -221,7 +252,7 @@ public class CellularNetworkService : ICellularNetworkService return CellularNetworkOperationResult.Failure(message); } - // 4. 获取 IP 端点信息 + // 4. 获取并验证 IP 端点信息 var (endPoints, hasAnyEndPoint) = await _configCopier.GetComAddrInfoAsync(config); if (!hasAnyEndPoint) { @@ -247,7 +278,7 @@ public class CellularNetworkService : ICellularNetworkService _context.UpdateNetworkConfigType(enableResult.ConfigType); _logger.LogInformation("更新网络配置类型: {ConfigType}", enableResult.ConfigType); - // 8. 检查所有网络端点的连接状态 + // 8. 检查网络端点连接状态 _logger.LogInformation("开始检查所有网络端点的连接状态"); var statusCheckResult = await _statusMonitor.CheckAllEndPointsStatusAsync(endPoints, enableResult.ConfigType); if (!statusCheckResult.IsSuccess) @@ -258,7 +289,7 @@ public class CellularNetworkService : ICellularNetworkService } _logger.LogInformation("网络端点状态检查完成,所有端点状态正常"); - // 9. 更新状态 + // 9. 更新网络状态并返回结果 var state = _context.GetNetworkState(); state.MarkAsStarted(); _logger.LogInformation("蜂窝网络配置 {ConfigKey} 启动成功,当前状态: {Status}", key, state.CurrentStatus); diff --git a/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs b/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs index 50e7b8c..7423eb4 100644 --- a/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs +++ b/CoreAgent.Infrastructure/Services/Network/NetworkStatusMonitor.cs @@ -264,17 +264,19 @@ public class NetworkStatusMonitor : INetworkStatusMonitor /// /// 通信地址 /// 端点类型 - private async Task CheckEndPointStatusAsync(string comAddr, string endPointType) + /// 命令类型 + /// 操作类型 + private async Task CheckEndPointAsync(string comAddr, string endPointType, string commandType, string operationType) { - var command = $"{_appSettings.WebSocketJsPath} {comAddr} '{_appSettings.WebSocketCommands.Stats.ToJson()}'"; - _logger.LogInformation("开始检查{EndPointType}端点状态,地址: {ComAddr}", endPointType, comAddr); + var command = $"{_appSettings.WebSocketJsPath} {comAddr} '{commandType}'"; + _logger.LogInformation("开始检查{EndPointType}端点{OperationType},地址: {ComAddr}", endPointType, operationType, comAddr); var result = await _commandExecutor.ExecuteCommandAsync(command, new CancellationTokenSource()); if (string.IsNullOrEmpty(result.Output)) { - _logger.LogWarning("{EndPointType}端点 {ComAddr} 状态检查失败: 返回数据为空", - endPointType, comAddr); + _logger.LogWarning("{EndPointType}端点 {ComAddr} {OperationType}检查失败: 返回数据为空", + endPointType, comAddr, operationType); return false; } @@ -288,35 +290,79 @@ public class NetworkStatusMonitor : INetworkStatusMonitor if (root.ValueKind == JsonValueKind.Object && root.EnumerateObject().Count() == 0) { - _logger.LogWarning("{EndPointType}端点 {ComAddr} 状态检查失败: 返回的JSON数据为空对象", - endPointType, comAddr); + _logger.LogWarning("{EndPointType}端点 {ComAddr} {OperationType}检查失败: 返回的JSON数据为空对象", + endPointType, comAddr, operationType); return false; } if (root.ValueKind == JsonValueKind.Array && root.GetArrayLength() == 0) { - _logger.LogWarning("{EndPointType}端点 {ComAddr} 状态检查失败: 返回的JSON数据为空数组", - endPointType, comAddr); + _logger.LogWarning("{EndPointType}端点 {ComAddr} {OperationType}检查失败: 返回的JSON数据为空数组", + endPointType, comAddr, operationType); return false; } } catch (JsonException) { - _logger.LogWarning("{EndPointType}端点 {ComAddr} 状态检查失败: 返回数据不是有效的JSON格式", - endPointType, comAddr); + _logger.LogWarning("{EndPointType}端点 {ComAddr} {OperationType}检查失败: 返回数据不是有效的JSON格式", + endPointType, comAddr, operationType); return false; } if (result.IsSuccess) { - _logger.LogInformation("{EndPointType}端点 {ComAddr} 状态检查成功,返回数据: {Data}", - endPointType, comAddr, parsedData); + _logger.LogInformation("{EndPointType}端点 {ComAddr} {OperationType}检查成功,返回数据: {Data}", + endPointType, comAddr, operationType, parsedData); return true; } else { var error = $"检查失败: {result.Error},返回数据: {result.Output}"; - _logger.LogWarning("{EndPointType}端点 {ComAddr} 状态检查失败: {Error}", - endPointType, comAddr, error); + _logger.LogWarning("{EndPointType}端点 {ComAddr} {OperationType}检查失败: {Error}", + endPointType, comAddr, operationType, error); + return false; + } + } + + /// + /// 检查单个端点的状态 + /// + /// 通信地址 + /// 端点类型 + private async Task CheckEndPointStatusAsync(string comAddr, string endPointType) + { + return await CheckEndPointAsync(comAddr, endPointType, _appSettings.WebSocketCommands.Stats.ToJson(), "状态"); + } + + /// + /// 检查单个端点的退出状态 + /// + /// 通信地址 + /// 端点类型 + private async Task CheckEndPointQuitAsync(string comAddr, string endPointType) + { + return await CheckEndPointAsync(comAddr, endPointType, _appSettings.WebSocketCommands.Quit.ToJson(), "退出状态"); + } + + /// + /// 检查 RAN 端点退出状态 + /// + /// RAN 端点信息 + /// 是否成功退出 + public async Task CheckRanQuitAsync(RanIPEndPoint ranEndPoint) + { + if (ranEndPoint == null) + { + _logger.LogWarning("RAN 端点未配置"); + return false; + } + + try + { + return await CheckEndPointQuitAsync(ranEndPoint.ComAddr, "RAN"); + } + catch (Exception ex) + { + _logger.LogError(ex, "检查 RAN 端点退出状态失败"); return false; } }