using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using LTEMvcApp.Models; using Newtonsoft.Json.Linq; using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using System.IO; using System.Text.Json; namespace LTEMvcApp.Services { /// /// WebSocket管理器服务 - 管理多个LTE客户端连接 /// public class WebSocketManagerService { #region 私有字段 private readonly ConcurrentDictionary _clients; private readonly ConcurrentDictionary _configs; private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; private List _testClientConfigs; // 只保留多个测试配置 private const int LogCacheSize = 10000; // 服务器最多缓存10000条最新日志 private readonly ConcurrentQueue _logCache = new ConcurrentQueue(); private readonly string _configsFilePath = "test_client_configs.json"; // 只保留多个配置文件路径 #endregion #region 事件 /// /// 客户端连接事件 /// public event EventHandler? ClientConnected; /// /// 客户端断开事件 /// public event EventHandler? ClientDisconnected; /// /// 日志接收事件 /// public event EventHandler<(string clientName, List logs)>? LogsReceived; /// /// 状态变化事件 /// public event EventHandler<(string clientName, ClientState state)>? StateChanged; #endregion #region 构造函数 /// /// 构造函数 /// public WebSocketManagerService(ILogger logger, IServiceProvider serviceProvider) { _clients = new ConcurrentDictionary(); _configs = new ConcurrentDictionary(); _logger = logger; _serviceProvider = serviceProvider; _testClientConfigs = new List(); // 初始化测试配置列表 LoadTestClientConfigs(); // 加载多个测试配置 _logger.LogInformation("WebSocketManagerService 初始化"); } /// /// 加载多个测试客户端配置 /// private void LoadTestClientConfigs() { try { if (File.Exists(_configsFilePath)) { var json = File.ReadAllText(_configsFilePath); _testClientConfigs = JsonSerializer.Deserialize>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new List(); _logger.LogInformation("成功从 {FilePath} 加载 {Count} 个测试客户端配置。", _configsFilePath, _testClientConfigs.Count); } else { _logger.LogWarning("多个配置文件 {FilePath} 未找到,将创建空配置列表。", _configsFilePath); _testClientConfigs = new List(); SaveTestClientConfigs(); } } catch (Exception ex) { _logger.LogError(ex, "加载多个测试客户端配置文件时出错。将使用空配置列表。"); _testClientConfigs = new List(); } } /// /// 保存多个测试客户端配置到文件 /// private void SaveTestClientConfigs() { try { var options = new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; var json = JsonSerializer.Serialize(_testClientConfigs, options); File.WriteAllText(_configsFilePath, json); _logger.LogInformation("多个测试客户端配置已成功保存到 {FilePath},共 {Count} 个配置。", _configsFilePath, _testClientConfigs.Count); } catch (Exception ex) { _logger.LogError(ex, "保存多个测试客户端配置文件失败。"); } } #endregion #region 公共方法 /// /// 添加客户端配置 /// /// 客户端配置 /// 是否成功添加 public bool AddClientConfig(ClientConfig config) { if (string.IsNullOrEmpty(config.Name)) { _logger.LogWarning("尝试添加空名称客户端配置"); return false; } _logger.LogInformation($"添加客户端配置: {config.Name}"); _configs[config.Name] = config; return true; } /// /// 移除客户端配置 /// /// 客户端名称 /// 是否成功移除 public bool RemoveClientConfig(string clientName) { _logger.LogInformation($"移除客户端配置: {clientName}"); if (_configs.TryRemove(clientName, out _)) { // 如果客户端正在运行,停止它 if (_clients.TryGetValue(clientName, out var client)) { client.Stop(); _clients.TryRemove(clientName, out _); } return true; } return false; } /// /// 启动客户端 /// /// 客户端名称 /// 是否成功启动 public bool StartClient(string clientName) { _logger.LogInformation($"启动客户端: {clientName}"); ClientConfig config; // 检查是否是测试客户端 var testConfig = _testClientConfigs.FirstOrDefault(c => c.Name == clientName); if (testConfig != null) { config = testConfig; _logger.LogInformation($"使用测试客户端配置: {config.Name}"); } else if (!_configs.TryGetValue(clientName, out config)) { _logger.LogWarning($"客户端配置不存在: {clientName}"); return false; } // 如果客户端已存在,先停止 if (_clients.TryGetValue(clientName, out var existingClient)) { existingClient.Stop(); _clients.TryRemove(clientName, out _); } // 通过依赖注入获取ILogger var logger = _serviceProvider.GetService(typeof(ILogger)) as ILogger; var client = new LTEClientWebSocket(config, logger!); // 订阅事件 client.ConnectionOpened += (sender, e) => OnClientConnected(client); client.ConnectionClosed += (sender, e) => OnClientDisconnected(client); client.LogsReceived += (sender, logs) => OnLogsReceived(clientName, logs); client.StateChanged += (sender, state) => OnStateChanged(clientName, state); // 启动客户端 client.Start(); // 添加到客户端列表 _clients[clientName] = client; return true; } /// /// 停止客户端 /// /// 客户端名称 /// 是否成功停止 public bool StopClient(string clientName) { _logger.LogInformation($"停止客户端: {clientName}"); if (_clients.TryGetValue(clientName, out var client)) { client.Stop(); _clients.TryRemove(clientName, out _); return true; } return false; } /// /// 获取客户端状态 /// /// 客户端名称 /// 客户端状态 public ClientState? GetClientState(string clientName) { if (_clients.TryGetValue(clientName, out var client)) { return client.State; } return null; } /// /// 获取所有客户端状态 /// /// 客户端状态字典 public Dictionary GetAllClientStates() { return _clients.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.State); } /// /// 获取客户端配置 /// /// 客户端名称 /// 客户端配置 public ClientConfig? GetClientConfig(string clientName) { _configs.TryGetValue(clientName, out var config); return config; } /// /// 获取所有客户端配置 /// /// 客户端配置列表 public List GetAllClientConfigs() { return _configs.Values.ToList(); } /// /// 获取客户端日志 /// /// 客户端名称 /// 客户端日志列表 public List? GetClientLogs(string clientName) { if (_clients.TryGetValue(clientName, out var client)) { return client.Client.Logs; } return null; } /// /// 重置客户端日志 /// /// 客户端名称 /// 是否成功重置 public bool ResetClientLogs(string clientName) { if (_clients.TryGetValue(clientName, out var client)) { client.ResetLogs(); return true; } return false; } /// /// 设置客户端日志配置 /// /// 客户端名称 /// 日志配置 /// 是否成功设置 public bool SetClientLogsConfig(string clientName, ClientLogsConfig logsConfig) { if (_clients.TryGetValue(clientName, out var client)) { client.SetLogsConfig(logsConfig, true); return true; } return false; } /// /// 播放/暂停客户端 /// /// 客户端名称 /// 是否成功操作 public bool PlayPauseClient(string clientName) { if (_clients.TryGetValue(clientName, out var client)) { client.PlayPause(); return true; } return false; } /// /// 发送消息到客户端 /// /// 客户端名称 /// 消息 /// 回调 /// 消息ID public int SendMessageToClient(string clientName, JObject message, Action? callback = null) { if (_clients.TryGetValue(clientName, out var client)) { return client.SendMessage(message, callback); } return -1; } /// /// 获取连接统计信息 /// /// 连接统计信息 public ConnectionStatistics GetConnectionStatistics() { var stats = new ConnectionStatistics { TotalClients = _clients.Count, ConnectedClients = _clients.Values.Count(c => c.IsConnected), DisconnectedClients = _clients.Values.Count(c => !c.IsConnected), TotalLogs = _clients.Values.Sum(c => c.Client.LogCount), ClientStates = GetAllClientStates() }; return stats; } /// /// 停止所有客户端 /// public void StopAllClients() { foreach (var client in _clients.Values) { client.Stop(); } _clients.Clear(); } /// /// 启动所有已配置的客户端 /// public void StartAllConfiguredClients() { foreach (var config in _configs.Values) { if (config.Enabled) { StartClient(config.Name); } } } /// /// 获取客户端实例 /// /// 客户端名称 /// 客户端实例 public LTEClientWebSocket? GetClientInstance(string clientName) { _clients.TryGetValue(clientName, out var client); return client; } /// /// 获取所有测试客户端配置 /// /// 测试客户端配置列表 public List GetAllTestClientConfigs() { return _testClientConfigs.ToList(); } /// /// 获取默认测试客户端配置(第一个配置或创建默认配置) /// /// 默认测试客户端配置 public ClientConfig GetDefaultTestClientConfig() { if (_testClientConfigs.Any()) { return _testClientConfigs.First(); } // 如果没有配置,创建默认配置 var defaultConfig = CreateDefaultTestConfig(); _testClientConfigs.Add(defaultConfig); SaveTestClientConfigs(); return defaultConfig; } /// /// 设置测试客户端配置 /// /// 测试客户端配置 /// 是否成功设置 public bool SetTestClientConfig(ClientConfig config) { if (string.IsNullOrEmpty(config.Name)) { _logger.LogWarning("尝试设置空名称的测试客户端配置"); return false; } if (string.IsNullOrEmpty(config.Address)) { _logger.LogWarning("尝试设置空地址的测试客户端配置"); return false; } _logger.LogInformation($"更新测试客户端配置: {config.Name} (地址: {config.Address})"); // 使用Address作为唯一key来检查是否存在 var existingConfigIndex = _testClientConfigs.FindIndex(c => c.Address == config.Address); if (existingConfigIndex >= 0) { // 更新现有配置 _testClientConfigs[existingConfigIndex] = config; _logger.LogInformation($"更新现有测试配置 (地址: {config.Address})"); } else { // 添加新配置 _testClientConfigs.Add(config); _logger.LogInformation($"添加新测试配置 (地址: {config.Address})"); } // 保存到文件 SaveTestClientConfigs(); return true; } /// /// 启动测试客户端 /// /// 是否成功启动 public bool StartTestClient() { var defaultConfig = GetDefaultTestClientConfig(); _logger.LogInformation("启动测试客户端: " + defaultConfig.Name); return StartClient(defaultConfig.Name); } /// /// 停止测试客户端 /// /// 是否成功停止 public bool StopTestClient() { var defaultConfig = GetDefaultTestClientConfig(); _logger.LogInformation("停止测试客户端: " + defaultConfig.Name); return StopClient(defaultConfig.Name); } /// /// 获取测试客户端实例 /// /// 测试客户端的WebSocket实例 public LTEClientWebSocket? GetTestClient() { var defaultConfig = GetDefaultTestClientConfig(); return GetClientInstance(defaultConfig.Name); } /// /// 获取所有测试客户端实例 /// /// 所有测试客户端的WebSocket实例列表 public List GetAllTestClients() { var testClients = new List(); foreach (var config in _testClientConfigs) { if (_clients.TryGetValue(config.Name, out var client)) { testClients.Add(client); } } return testClients; } /// /// 获取所有测试客户端配置和状态 /// /// 测试客户端配置和状态列表 public List GetAllTestClientsWithState() { var result = new List(); foreach (var config in _testClientConfigs) { var client = GetClientInstance(config.Name); var state = client?.State ?? ClientState.Stop; result.Add(new { Config = config, State = state, Client = client }); } return result; } /// /// 创建默认测试配置 /// /// 默认测试配置 private ClientConfig CreateDefaultTestConfig() { var layers = new Dictionary(); foreach(var layerName in LogLayerTypes.AllLayers.Where(l => l != "EVENT")) { layers[layerName] = new LogLayerConfig { Level = LogLayerTypes.GetDefaultLevel(layerName), Filter = "warn", MaxSize = 1000, Payload = false }; } // Set some specific payloads to true if(layers.ContainsKey("PHY")) layers["PHY"].Payload = true; if(layers.ContainsKey("MAC")) layers["MAC"].Payload = true; if(layers.ContainsKey("RRC")) layers["RRC"].Payload = true; if(layers.ContainsKey("NAS")) layers["NAS"].Payload = true; return new ClientConfig { Name = "TestClient", Enabled = true, Address = "192.168.13.12:9001", Ssl = false, ReconnectDelay = 15000, Password = "test123", Logs = new ClientLogsConfig { Layers = layers, Signal = true, Cch = true } }; } /// /// 根据地址获取测试客户端配置 /// /// 服务器地址 /// 测试客户端配置 public ClientConfig? GetTestClientConfigByAddress(string address) { return _testClientConfigs.FirstOrDefault(c => c.Address == address); } /// /// 删除测试客户端配置 /// /// 服务器地址 /// 是否成功删除 public bool RemoveTestClientConfig(string address) { var config = _testClientConfigs.FirstOrDefault(c => c.Address == address); if (config != null) { _testClientConfigs.Remove(config); SaveTestClientConfigs(); _logger.LogInformation($"删除测试客户端配置 (地址: {address})"); return true; } return false; } /// /// 获取当前缓存的日志 /// public IEnumerable GetLogCache() { // 使用线程安全的方式获取日志列表 lock (_logCache) { var logs = _logCache.ToList(); _logger.LogDebug("GetLogCache: 返回 {Count} 条日志", logs.Count); return logs; } } /// /// 获取当前缓存的日志总数 /// public int GetLogCacheCount() { var count = _logCache.Count; _logger.LogDebug("GetLogCacheCount: 当前缓存 {Count} 条日志", count); return count; } /// /// 清空日志缓存 /// public void ClearLogCache() { _logger.LogInformation("清空日志缓存"); lock (_logCache) { while (_logCache.TryDequeue(out _)) { // 清空所有日志 } } } /// /// 重置日志缓存(清空并重新初始化) /// public void ResetLogCache() { _logger.LogInformation("重置日志缓存"); ClearLogCache(); // 可以在这里添加其他重置逻辑 } /// /// 手动添加日志到缓存 /// /// 日志对象 public void AddLogToCache(LTELog log) { if (log != null) { lock (_logCache) { _logCache.Enqueue(log); _logger.LogDebug("手动添加日志到缓存: {Layer} - {Message}", log.Layer, log.Message); // 维持缓存大小 while (_logCache.Count > LogCacheSize) { _logCache.TryDequeue(out _); } } } } /// /// 手动添加多个日志到缓存 /// /// 日志列表 public void AddLogsToCache(List logs) { if (logs != null && logs.Any()) { lock (_logCache) { foreach (var log in logs) { _logCache.Enqueue(log); } _logger.LogInformation("手动添加 {Count} 条日志到缓存", logs.Count); // 维持缓存大小 while (_logCache.Count > LogCacheSize) { _logCache.TryDequeue(out _); } } } } /// /// 获取日志缓存详细状态(调试用) /// /// 缓存状态信息 public object GetLogCacheStatus() { lock (_logCache) { var logs = _logCache.ToList(); var sampleLogs = logs.TakeLast(3).Select(log => new { timestamp = log.Timestamp, layer = log.Layer, message = log.Message?.Substring(0, Math.Min(50, log.Message?.Length ?? 0)) + "..." }).ToList(); return new { totalCount = _logCache.Count, actualCount = logs.Count, cacheSize = LogCacheSize, sampleLogs = sampleLogs, timestamp = DateTime.UtcNow }; } } #endregion #region 私有方法 /// /// 客户端连接事件处理 /// private void OnClientConnected(LTEClientWebSocket client) { _logger.LogInformation($"客户端已连接: {client.Client.Config.Name}"); ClientConnected?.Invoke(this, client); } /// /// 客户端断开事件处理 /// private void OnClientDisconnected(LTEClientWebSocket client) { _logger.LogWarning($"客户端已断开: {client.Client.Config.Name}"); ClientDisconnected?.Invoke(this, client); } /// /// 日志接收事件处理 /// private void OnLogsReceived(string clientName, List logs) { _logger.LogInformation($"客户端 {clientName} 收到日志: {logs.Count} 条"); if (logs != null && logs.Any()) { lock (_logCache) { // 将新日志存入中央缓存 foreach (var log in logs) { if (log != null) { _logCache.Enqueue(log); _logger.LogDebug($"客户端 {clientName} 添加日志到缓存: {log.Layer} - {log.Message}"); } } // 维持缓存大小 while (_logCache.Count > LogCacheSize) { _logCache.TryDequeue(out _); } _logger.LogInformation($"客户端 {clientName} 日志已添加到缓存,当前缓存总数: {_logCache.Count}"); } } LogsReceived?.Invoke(this, (clientName, logs)); } /// /// 状态变化事件处理 /// private void OnStateChanged(string clientName, ClientState state) { _logger.LogInformation($"客户端 {clientName} 状态变更: {state}"); StateChanged?.Invoke(this, (clientName, state)); } #endregion } /// /// 连接统计信息 /// public class ConnectionStatistics { /// /// 总客户端数 /// public int TotalClients { get; set; } /// /// 已连接客户端数 /// public int ConnectedClients { get; set; } /// /// 未连接客户端数 /// public int DisconnectedClients { get; set; } /// /// 总日志数 /// public int TotalLogs { get; set; } /// /// 客户端状态字典 /// public Dictionary ClientStates { get; set; } = new(); } }