From 33f2dad077d59f66f8ba014e546a44d7146485c6 Mon Sep 17 00:00:00 2001
From: root <295172551@qq.com>
Date: Mon, 23 Jun 2025 23:05:16 +0800
Subject: [PATCH] 1
---
LTEMvcApp/Models/LTEClient.cs | 2 +-
LTEMvcApp/Services/LTEClientWebSocket.cs | 274 +++++++++++++++++++----
2 files changed, 232 insertions(+), 44 deletions(-)
diff --git a/LTEMvcApp/Models/LTEClient.cs b/LTEMvcApp/Models/LTEClient.cs
index f46cc12..957de92 100644
--- a/LTEMvcApp/Models/LTEClient.cs
+++ b/LTEMvcApp/Models/LTEClient.cs
@@ -559,7 +559,7 @@ public class LTEClient
/// 小区ID
/// 小区配置
/// 小区对象
- private LTECell AddCell(int id, Dictionary config)
+ public LTECell AddCell(int id, Dictionary config)
{
var cell = new LTECell(id, config);
diff --git a/LTEMvcApp/Services/LTEClientWebSocket.cs b/LTEMvcApp/Services/LTEClientWebSocket.cs
index 2131035..2429199 100644
--- a/LTEMvcApp/Services/LTEClientWebSocket.cs
+++ b/LTEMvcApp/Services/LTEClientWebSocket.cs
@@ -39,6 +39,13 @@ namespace LTEMvcApp.Services
private const int ServerMessageCacheLimit = 1000;
private readonly ConcurrentQueue _sentMessages = new ConcurrentQueue();
private readonly ConcurrentQueue _receivedMessages = new ConcurrentQueue();
+
+ // 统计更新相关字段
+ private int _statsPollDelay = 1000; // 默认1秒,对应JavaScript版本的_statsPolldelay
+ private bool _isFirstStatsUpdate = true;
+
+ // 防止重复调用的标志
+ private bool _isSocketReady = false;
#endregion
#region 事件
@@ -191,6 +198,7 @@ namespace LTEMvcApp.Services
{
SetState(ClientState.Stop);
StopTimers();
+ _isSocketReady = false; // 重置连接状态标志
}
///
@@ -394,6 +402,31 @@ namespace LTEMvcApp.Services
_logGetId = SendMessage(message, LogGetParse);
}
+ ///
+ /// 手动触发统计更新
+ ///
+ public void TriggerStatsUpdate()
+ {
+ UpdateStats();
+ }
+
+ ///
+ /// 重置统计信息
+ ///
+ public void ResetStatistics()
+ {
+ ResetStats();
+ }
+
+ ///
+ /// 获取当前统计更新间隔
+ ///
+ /// 统计更新间隔(毫秒)
+ public int GetStatsUpdateInterval()
+ {
+ return _statsPollDelay;
+ }
+
#endregion
#region 私有方法
@@ -419,6 +452,9 @@ namespace LTEMvcApp.Services
StopTimers();
CloseComponents();
+
+ // 重置连接状态标志
+ _isSocketReady = false;
if (State == ClientState.Connected)
{
@@ -504,7 +540,14 @@ namespace LTEMvcApp.Services
///
private void OnSocketReady()
{
- if (_webSocket == null) return;
+ if (_webSocket == null || _isSocketReady)
+ {
+ _logger.LogDebug($"[{_config.Name}] OnSocketReady被跳过: WebSocket={_webSocket != null}, IsSocketReady={_isSocketReady}");
+ return; // 防止重复调用
+ }
+
+ _logger.LogInformation($"[{_config.Name}] WebSocket准备就绪,开始初始化");
+ _isSocketReady = true; // 设置标志
// 切换到正常的消息处理函数
_webSocket.MessageReceived -= OnSocketMessage0;
@@ -516,9 +559,11 @@ namespace LTEMvcApp.Services
var firstCon = _config.Logs.Layers.Count == 0;
// 获取配置
+ _logger.LogDebug($"[{_config.Name}] 发送config_get请求");
SendMessage(new JObject { ["message"] = "config_get" }, config =>
{
Console.WriteLine("配置已接收");
+ _logger.LogInformation($"[{_config.Name}] 配置已接收");
_client.ResetLogs();
@@ -552,6 +597,8 @@ namespace LTEMvcApp.Services
foreach (var cell in cells)
{
// 添加小区配置
+
+ _client.AddCell(Convert.ToInt32(cell.Key), cells);
}
}
}
@@ -571,6 +618,9 @@ namespace LTEMvcApp.Services
{
SetLogsConfig(_config.Logs);
}
+
+ // 启动统计更新(对应JavaScript版本的_updateStats(true))
+ UpdateStats(true);
});
}
@@ -693,58 +743,73 @@ namespace LTEMvcApp.Services
{
if (logItem is JObject logObj)
{
- //var logData = logObj.ToObject>() ?? new Dictionary();
-
- // 创建LTELog对象
- var log = JsonConvert.DeserializeObject(logObj.ToString()); //new LTELog(logData);
-
- // 处理消息和数据
- if (log.Data is List dataList && dataList.Count > 0)
+ try
{
- log.Message = dataList[0];
- dataList.RemoveAt(0);
- }
+ // 使用JsonConvert反序列化创建LTELog对象
+ var log = JsonConvert.DeserializeObject(logObj.ToString());
+ if (log == null) continue;
- // 设置方向
- log.Direction = _client.DirConvert(log);
+ // 处理消息和数据 - 从data中提取第一条作为Message(与JavaScript版本保持一致)
+ if (log.Data is List dataList && dataList.Count > 0)
+ {
+ log.Message = dataList[0];
+ dataList.RemoveAt(0);
+ }
- // 处理信息字段
- if (log.Info != null)
- {
- log.Info = _client.StringToId(log.Info.ToString());
- }
+ // 设置方向(与JavaScript版本保持一致)
+ log.Direction = _client.DirConvert(log);
- // 处理PHY层的信号记录
- if (log.Layer == "PHY" && log.Data is List data)
- {
- var signalRecord = new Dictionary();
- for (int j = data.Count - 1; j >= 0; j--)
+ // 处理信息字段(与JavaScript版本保持一致)
+ if (log.Info != null)
{
- var line = data[j];
- var match = Regex.Match(line, @"Link:\s([\w\d]+)@(\d+)");
- if (match.Success)
- {
- var linkName = match.Groups[1].Value;
- var offset = uint.Parse(match.Groups[2].Value);
- signalRecord[linkName] = new { offset = offset };
- data.RemoveAt(j);
- }
+ log.Info = _client.StringToId(log.Info.ToString());
}
- if (signalRecord.Count > 0)
+ // 处理PHY层的信号记录(与JavaScript版本保持一致)
+ if (log.Layer == "PHY" && log.Data is List data)
{
- //log.SignalRecord = signalRecord;
- _client.HasSignalRecord = true;
+ var signalRecord = new Dictionary();
+ for (int j = data.Count - 1; j >= 0; j--)
+ {
+ var line = data[j];
+ var match = Regex.Match(line, @"Link:\s([\w\d]+)@(\d+)");
+ if (match.Success)
+ {
+ var linkName = match.Groups[1].Value;
+ var offset = uint.Parse(match.Groups[2].Value);
+ signalRecord[linkName] = new { offset = offset };
+ data.RemoveAt(j);
+ }
+ }
+
+ if (signalRecord.Count > 0)
+ {
+ log.SignalRecord = signalRecord; // 修复:正确设置信号记录
+ _client.HasSignalRecord = true;
+ }
}
- }
- log.Client = _client;
- logList.Add(log);
+ log.Client = _client;
+ logList.Add(log);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"[{_config.Name}] 解析日志项时出错: {ex.Message}");
+ // 继续处理下一个日志项,不中断整个流程
+ }
}
}
- _client.ParseLogList(logList, true);
- //_client.ParseLogList(logList, true);
- LogsReceived?.Invoke(this, logList);
+
+ // 调用日志解析(与JavaScript版本保持一致)
+ if (logList.Count > 0)
+ {
+ _client.ParseLogList(logList, true);
+
+ // 更新日志管理器(对应JavaScript版本的lteLogs.updateLogs())
+ _client.LogsManager.UpdateLogs();
+
+ LogsReceived?.Invoke(this, logList);
+ }
}
}
@@ -811,8 +876,8 @@ namespace LTEMvcApp.Services
_reconnectTimer?.Dispose();
_reconnectTimer = null;
- _statsTimer?.Dispose();
- _statsTimer = null;
+ StopStatsTimer(); // 使用专门的统计定时器停止方法
+ ResetStats(); // 重置统计信息
_messageDeferTimer?.Dispose();
_messageDeferTimer = null;
@@ -886,6 +951,129 @@ namespace LTEMvcApp.Services
Console.WriteLine("需要认证,请输入密码");
}
+ #region 统计更新相关方法
+
+ ///
+ /// 设置刷新延迟时间
+ ///
+ /// 延迟时间(毫秒)
+ public void SetRefreshDelay(int delay)
+ {
+ _statsPollDelay = delay;
+ }
+
+ ///
+ /// 获取刷新延迟时间
+ ///
+ /// 延迟时间(毫秒)
+ public int GetRefreshDelay()
+ {
+ return _statsPollDelay;
+ }
+
+ ///
+ /// 更新统计信息(对应JavaScript版本的_updateStats)
+ ///
+ /// 是否为第一次更新
+ private void UpdateStats(bool first = false)
+ {
+ if (_disposed || _webSocket?.State != WebSocketState.Open) return;
+
+ var msg = new JObject { ["message"] = "stats" };
+
+ // 准备统计消息(对应JavaScript版本的tab.statsPrepare)
+ PrepareStatsMessage(msg);
+
+ SendMessage(msg, response =>
+ {
+ if (_disposed) return;
+
+ // 第一次调用会重置统计
+ if (first || _isFirstStatsUpdate)
+ {
+ ResetStats();
+ _isFirstStatsUpdate = false;
+
+ // 第一次调用后启动定时器循环
+ StartStatsTimer();
+ return;
+ }
+
+ // 发送统计事件(对应JavaScript版本的sendEvent)
+ StatsReceived?.Invoke(this, response);
+
+ // 添加统计到统计面板(对应JavaScript版本的lteStatsTab.add)
+ AddStatsToPanel(response);
+
+ // 设置下一次统计更新(对应JavaScript版本的定时器循环)
+ StartStatsTimer();
+ });
+ }
+
+ ///
+ /// 准备统计消息
+ ///
+ /// 统计消息
+ private void PrepareStatsMessage(JObject msg)
+ {
+ // 这里可以添加统计消息的准备工作
+ // 对应JavaScript版本中的tab.statsPrepare(msg)
+ _logger.LogDebug($"[{_config.Name}] 准备统计消息: {msg}");
+ }
+
+ ///
+ /// 重置统计信息(对应JavaScript版本的_resetStats)
+ ///
+ private void ResetStats()
+ {
+ // 重置统计信息,对应JavaScript版本的lteStatsTab.add(this.getName(), {cpu: {global: 0}})
+ var resetStats = new JObject
+ {
+ ["cpu"] = new JObject { ["global"] = 0 }
+ };
+
+ AddStatsToPanel(resetStats);
+ _logger.LogDebug($"[{_config.Name}] 重置统计信息");
+ }
+
+ ///
+ /// 添加统计到面板
+ ///
+ /// 统计信息
+ private void AddStatsToPanel(JObject stats)
+ {
+ // 这里应该将统计信息添加到统计面板
+ // 对应JavaScript版本中的lteStatsTab.add(this.getName(), resp)
+ _logger.LogDebug($"[{_config.Name}] 添加统计到面板: {stats}");
+
+ // 可以在这里实现具体的统计面板更新逻辑
+ // 或者通过事件通知其他组件更新统计信息
+ }
+
+ ///
+ /// 启动统计更新定时器
+ ///
+ private void StartStatsTimer()
+ {
+ if (_statsTimer != null)
+ {
+ _statsTimer.Dispose();
+ }
+
+ _statsTimer = new Timer(_ => UpdateStats(), null, _statsPollDelay, Timeout.Infinite);
+ }
+
+ ///
+ /// 停止统计更新定时器
+ ///
+ private void StopStatsTimer()
+ {
+ _statsTimer?.Dispose();
+ _statsTimer = null;
+ }
+
+ #endregion
+
#endregion
#region IDisposable