root 1 month ago
parent
commit
fb9eb80cba
  1. 96
      LTEMvcApp/Services/WebSocketManagerService.cs
  2. 46
      LTEMvcApp/Views/Home/TestClientConfig.cshtml

96
LTEMvcApp/Services/WebSocketManagerService.cs

@ -7,6 +7,8 @@ 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
{
@ -25,6 +27,7 @@ namespace LTEMvcApp.Services
private ClientConfig _testClientConfig;
private const int LogCacheSize = 10000; // 服务器最多缓存10000条最新日志
private readonly ConcurrentQueue<LTELog> _logCache = new ConcurrentQueue<LTELog>();
private readonly string _configFilePath = "test_client_config.json";
#endregion
@ -65,41 +68,87 @@ namespace LTEMvcApp.Services
_logger = logger;
_serviceProvider = serviceProvider;
// 初始化测试客户端配置
_testClientConfig = new ClientConfig
LoadTestClientConfig();
_logger.LogInformation("WebSocketManagerService 初始化");
}
/// <summary>
/// 加载测试客户端配置
/// </summary>
private void LoadTestClientConfig()
{
try
{
if (File.Exists(_configFilePath))
{
var json = File.ReadAllText(_configFilePath);
_testClientConfig = JsonSerializer.Deserialize<ClientConfig>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
_logger.LogInformation("成功从 {FilePath} 加载测试客户端配置。", _configFilePath);
}
else
{
_logger.LogWarning("配置文件 {FilePath} 未找到,将创建并使用默认配置。", _configFilePath);
_testClientConfig = GetDefaultTestConfig();
SaveTestClientConfig();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "加载或创建测试客户端配置文件时出错。将使用默认配置。");
_testClientConfig = GetDefaultTestConfig();
}
}
/// <summary>
/// 保存测试客户端配置到文件
/// </summary>
private void SaveTestClientConfig()
{
try
{
var options = new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var json = JsonSerializer.Serialize(_testClientConfig, options);
File.WriteAllText(_configFilePath, json);
_logger.LogInformation("测试客户端配置已成功保存到 {FilePath}。", _configFilePath);
}
catch (Exception ex)
{
_logger.LogError(ex, "保存测试客户端配置文件失败。");
}
}
private ClientConfig GetDefaultTestConfig()
{
return new ClientConfig
{
Name = "TestClient",
Enabled = true,
Address = "192.168.13.12:9001",
Ssl = false,
ReconnectDelay = 15000,
Pause = false,
Readonly = false,
SkipLogMenu = false,
Locked = false,
Active = true,
Password = "test123",
Logs = new Dictionary<string, object>
{
["layers"] = new Dictionary<string, object>
{
["PHY"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = true, ["filter"] = "info" },
["MAC"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = true, ["filter"] = "info" },
["RLC"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" },
["PDCP"] = new Dictionary<string, object> { ["level"] = "warn", ["max_size"] = 1, ["payload"] = false, ["filter"] = "warn" },
["RRC"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = true, ["filter"] = "debug" },
["NAS"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = true, ["filter"] = "debug" },
["S1AP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" },
["NGAP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" },
["GTPU"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" },
["X2AP"] = new Dictionary<string, object> { ["level"] = "debug", ["max_size"] = 1, ["payload"] = false, ["filter"] = "debug" },
["XnAP"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" },
["M2AP"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" },
["EVENT"] = new Dictionary<string, object> { ["level"] = "info", ["max_size"] = 1, ["payload"] = false, ["filter"] = "info" }
}
["PHY"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = true },
["MAC"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = true },
["RLC"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["PDCP"] = new LogLayerConfig { Level = "warn", Filter = "warn", MaxSize = 1000, Payload = false },
["RRC"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = true },
["NAS"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = true },
["S1AP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["NGAP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["GTPU"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["X2AP"] = new LogLayerConfig { Level = "debug", Filter = "warn", MaxSize = 1000, Payload = false },
["XnAP"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false },
["M2AP"] = new LogLayerConfig { Level = "info", Filter = "warn", MaxSize = 1000, Payload = false }
},
["signal"] = true,
["cch"] = true
}
};
_logger.LogInformation("WebSocketManagerService 初始化");
}
#endregion
@ -408,6 +457,7 @@ namespace LTEMvcApp.Services
_logger.LogInformation($"更新测试客户端配置: {config.Name}");
_testClientConfig = config;
SaveTestClientConfig();
return true;
}

46
LTEMvcApp/Views/Home/TestClientConfig.cshtml

@ -3,40 +3,30 @@
var testConfig = ViewBag.TestConfig as LTEMvcApp.Models.ClientConfig;
// 只保留不含 EVENT 的日志层
var allLayers = LTEMvcApp.Models.LogLayerTypes.AllLayers.Where(l => l != "EVENT").ToArray();
var layerConfigs = new Dictionary<string, Dictionary<string, object>>();
if (testConfig?.Logs?.ContainsKey("layers") == true && testConfig.Logs["layers"] is Dictionary<string, object> layers)
var layerConfigs = new Dictionary<string, LTEMvcApp.Models.LogLayerConfig>();
if (testConfig?.Logs?.ContainsKey("layers") == true && testConfig.Logs["layers"] is System.Text.Json.JsonElement layersElement)
{
foreach (var layer in allLayers)
var layers = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, LTEMvcApp.Models.LogLayerConfig>>(layersElement.GetRawText(), new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true })
?? new Dictionary<string, LTEMvcApp.Models.LogLayerConfig>();
foreach (var layerName in allLayers)
{
var config = new Dictionary<string, object>();
if (layers.ContainsKey(layer) && layers[layer] is Dictionary<string, object> layerConfig)
if (layers.TryGetValue(layerName, out var config))
{
config["level"] = layerConfig.ContainsKey("level") ? layerConfig["level"]?.ToString() : LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer);
config["filter"] = layerConfig.ContainsKey("filter") ? layerConfig["filter"]?.ToString() : "warn";
config["maxSize"] = layerConfig.ContainsKey("max_size") && layerConfig["max_size"] != null ? Convert.ToInt32(layerConfig["max_size"]) : 1;
config["payload"] = layerConfig.ContainsKey("payload") && layerConfig["payload"] != null ? Convert.ToBoolean(layerConfig["payload"]) : false;
layerConfigs[layerName] = config;
}
else
{
config["level"] = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer);
config["filter"] = "warn";
config["maxSize"] = 1;
config["payload"] = false;
layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
}
layerConfigs[layer] = config;
}
}
else
{
foreach (var layer in allLayers)
foreach (var layerName in allLayers)
{
layerConfigs[layer] = new Dictionary<string, object>
{
["level"] = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layer),
["filter"] = "warn",
["maxSize"] = 1,
["payload"] = false
};
layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
}
}
}
@ -127,17 +117,13 @@
@foreach (var layer in allLayers)
{
var config = layerConfigs[layer];
var level = config["level"]?.ToString();
var filter = config["filter"]?.ToString();
var maxSize = Convert.ToInt32(config["maxSize"]);
var payload = Convert.ToBoolean(config["payload"]);
<tr>
<td><strong>@layer</strong></td>
<td>
<select class="form-control form-control-sm" name="layers[@layer][level]">
@foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels)
{
if (logLevel == level)
if (logLevel == config.Level)
{
<option value="@logLevel" selected>@logLevel.ToUpper()</option>
}
@ -152,7 +138,7 @@
<select class="form-control form-control-sm" name="layers[@layer][filter]">
@foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels)
{
if (logLevel == filter)
if (logLevel == config.Filter)
{
<option value="@logLevel" selected>@logLevel.ToUpper()</option>
}
@ -164,11 +150,11 @@
</select>
</td>
<td>
<input type="number" class="form-control form-control-sm" name="layers[@layer][max_size]" value="@maxSize" min="1" max="1000">
<input type="number" class="form-control form-control-sm" name="layers[@layer][max_size]" value="@config.MaxSize" min="1" max="1000">
</td>
<td>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="layers[@layer][payload]" @(payload ? "checked" : "")>
<input type="checkbox" class="form-check-input" name="layers[@layer][payload]" @(config.Payload ? "checked" : "")>
</div>
</td>
</tr>

Loading…
Cancel
Save