You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
15 KiB
300 lines
15 KiB
@{
|
|
ViewData["Title"] = "测试客户端配置";
|
|
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, LTEMvcApp.Models.LogLayerConfig>();
|
|
|
|
if (testConfig?.Logs?.ContainsKey("layers") == true && testConfig.Logs["layers"] is System.Text.Json.JsonElement layersElement)
|
|
{
|
|
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)
|
|
{
|
|
if (layers.TryGetValue(layerName, out var config))
|
|
{
|
|
layerConfigs[layerName] = config;
|
|
}
|
|
else
|
|
{
|
|
layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var layerName in allLayers)
|
|
{
|
|
layerConfigs[layerName] = new LTEMvcApp.Models.LogLayerConfig { Level = LTEMvcApp.Models.LogLayerTypes.GetDefaultLevel(layerName) };
|
|
}
|
|
}
|
|
}
|
|
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">测试客户端配置</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<form id="testClientConfigForm">
|
|
<!-- 基本配置 -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="name">客户端名称</label>
|
|
<input type="text" class="form-control" id="name" name="name" value="@testConfig?.Name" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="address">服务器地址</label>
|
|
<input type="text" class="form-control" id="address" name="address" value="@testConfig?.Address" placeholder="192.168.13.12:9001">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="password">密码</label>
|
|
<input type="password" class="form-control" id="password" name="password" value="@testConfig?.Password">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="reconnectDelay">重连延迟 (毫秒)</label>
|
|
<input type="number" class="form-control" id="reconnectDelay" name="reconnectDelay" value="@testConfig?.ReconnectDelay">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input type="checkbox" class="form-check-input" id="enabled" name="enabled" @(testConfig?.Enabled == true ? "checked" : "")>
|
|
<label class="form-check-label" for="enabled">启用</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input type="checkbox" class="form-check-input" id="ssl" name="ssl" @(testConfig?.Ssl == true ? "checked" : "")>
|
|
<label class="form-check-label" for="ssl">使用SSL</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input type="checkbox" class="form-check-input" id="readonly" name="readonly" @(testConfig?.Readonly == true ? "checked" : "")>
|
|
<label class="form-check-label" for="readonly">只读模式</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 日志层配置 -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12">
|
|
<h5>日志层配置</h5>
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-sm">
|
|
<thead class="table-dark">
|
|
<tr>
|
|
<th>日志层</th>
|
|
<th>级别</th>
|
|
<th>过滤器</th>
|
|
<th>最大大小</th>
|
|
<th>包含负载</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var layer in allLayers)
|
|
{
|
|
var config = layerConfigs[layer];
|
|
<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 == config.Level)
|
|
{
|
|
<option value="@logLevel" selected>@logLevel.ToUpper()</option>
|
|
}
|
|
else
|
|
{
|
|
<option value="@logLevel">@logLevel.ToUpper()</option>
|
|
}
|
|
}
|
|
</select>
|
|
</td>
|
|
<td>
|
|
<select class="form-control form-control-sm" name="layers[@layer][filter]">
|
|
@foreach (var logLevel in LTEMvcApp.Models.LogLayerTypes.LogLevels)
|
|
{
|
|
if (logLevel == config.Filter)
|
|
{
|
|
<option value="@logLevel" selected>@logLevel.ToUpper()</option>
|
|
}
|
|
else
|
|
{
|
|
<option value="@logLevel">@logLevel.ToUpper()</option>
|
|
}
|
|
}
|
|
</select>
|
|
</td>
|
|
<td>
|
|
<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]" @(config.Payload ? "checked" : "")>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 操作按钮 -->
|
|
<div class="row mt-4">
|
|
<div class="col-md-12">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save"></i> 保存配置
|
|
</button>
|
|
<button type="button" class="btn btn-success" onclick="startTestClient()">
|
|
<i class="fas fa-play"></i> 启动测试客户端
|
|
</button>
|
|
<button type="button" class="btn btn-danger" onclick="stopTestClient()">
|
|
<i class="fas fa-stop"></i> 停止测试客户端
|
|
</button>
|
|
<a href="@Url.Action("ClientMessages", "Home", new { clientName = testConfig?.Name })" class="btn btn-info">
|
|
<i class="fas fa-list"></i> 查看消息队列
|
|
</a>
|
|
<button type="button" class="btn btn-secondary" onclick="resetToDefaults()">
|
|
<i class="fas fa-undo"></i> 重置为默认值
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
$(document).ready(function() {
|
|
$('#testClientConfigForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
saveTestClientConfig();
|
|
});
|
|
});
|
|
|
|
function saveTestClientConfig() {
|
|
var formData = {
|
|
name: $('#name').val(),
|
|
address: $('#address').val(),
|
|
password: $('#password').val(),
|
|
reconnectDelay: parseInt($('#reconnectDelay').val()) || 15000,
|
|
enabled: $('#enabled').is(':checked'),
|
|
ssl: $('#ssl').is(':checked'),
|
|
readonly: $('#readonly').is(':checked'),
|
|
logs: {
|
|
layers: {}
|
|
}
|
|
};
|
|
|
|
// 构建日志层配置
|
|
var layers = @Html.Raw(Json.Serialize(allLayers));
|
|
layers.forEach(function(layer) {
|
|
var level = $(`select[name="layers[${layer}][level]"]`).val();
|
|
var filter = $(`select[name="layers[${layer}][filter]"]`).val();
|
|
var maxSize = parseInt($(`input[name="layers[${layer}][max_size]"]`).val()) || 1;
|
|
var payload = $(`input[name="layers[${layer}][payload]"]`).is(':checked');
|
|
|
|
formData.logs.layers[layer] = {
|
|
level: level,
|
|
maxSize: maxSize,
|
|
payload: payload,
|
|
filter: filter
|
|
};
|
|
});
|
|
|
|
$.ajax({
|
|
url: '/api/websocket/test-client-config',
|
|
type: 'POST',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify(formData),
|
|
success: function(response) {
|
|
alert('配置保存成功!');
|
|
location.reload();
|
|
},
|
|
error: function(xhr) {
|
|
alert('保存配置失败:' + xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
function startTestClient() {
|
|
$.ajax({
|
|
url: '/api/websocket/test-client/start',
|
|
type: 'POST',
|
|
success: function(response) {
|
|
alert('测试客户端启动成功!');
|
|
},
|
|
error: function(xhr) {
|
|
alert('启动测试客户端失败:' + xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
function stopTestClient() {
|
|
$.ajax({
|
|
url: '/api/websocket/test-client/stop',
|
|
type: 'POST',
|
|
success: function(response) {
|
|
alert('测试客户端停止成功!');
|
|
},
|
|
error: function(xhr) {
|
|
alert('停止测试客户端失败:' + xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
function resetToDefaults() {
|
|
if (confirm('确定要重置为默认配置吗?')) {
|
|
// 重置为默认值
|
|
var defaultLevels = {
|
|
'PHY': 'info', 'MAC': 'info', 'RLC': 'info', 'PDCP': 'warn',
|
|
'RRC': 'debug', 'NAS': 'debug', 'S1AP': 'debug', 'NGAP': 'debug',
|
|
'GTPU': 'info', 'X2AP': 'debug', 'XnAP': 'info', 'M2AP': 'info'
|
|
};
|
|
|
|
Object.keys(defaultLevels).forEach(function(layer) {
|
|
$(`select[name="layers[${layer}][level]"]`).val(defaultLevels[layer]);
|
|
$(`select[name="layers[${layer}][filter]"]`).val('warn');
|
|
$(`input[name="layers[${layer}][max_size]"]`).val(1);
|
|
$(`input[name="layers[${layer}][payload]"]`).prop('checked', false);
|
|
});
|
|
|
|
// 设置一些层的 payload 为 true
|
|
['PHY', 'MAC', 'RRC', 'NAS'].forEach(function(layer) {
|
|
$(`input[name="layers[${layer}][payload]"]`).prop('checked', true);
|
|
});
|
|
|
|
alert('已重置为默认配置!');
|
|
}
|
|
}
|
|
</script>
|
|
}
|