Browse Source

1

feature/LteClientLogFun
root 1 month ago
parent
commit
33f2dad077
  1. 2
      LTEMvcApp/Models/LTEClient.cs
  2. 274
      LTEMvcApp/Services/LTEClientWebSocket.cs

2
LTEMvcApp/Models/LTEClient.cs

@ -559,7 +559,7 @@ public class LTEClient
/// <param name="id">小区ID</param>
/// <param name="config">小区配置</param>
/// <returns>小区对象</returns>
private LTECell AddCell(int id, Dictionary<string, object> config)
public LTECell AddCell(int id, Dictionary<string, object> config)
{
var cell = new LTECell(id, config);

274
LTEMvcApp/Services/LTEClientWebSocket.cs

@ -39,6 +39,13 @@ namespace LTEMvcApp.Services
private const int ServerMessageCacheLimit = 1000;
private readonly ConcurrentQueue<string> _sentMessages = new ConcurrentQueue<string>();
private readonly ConcurrentQueue<string> _receivedMessages = new ConcurrentQueue<string>();
// 统计更新相关字段
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; // 重置连接状态标志
}
/// <summary>
@ -394,6 +402,31 @@ namespace LTEMvcApp.Services
_logGetId = SendMessage(message, LogGetParse);
}
/// <summary>
/// 手动触发统计更新
/// </summary>
public void TriggerStatsUpdate()
{
UpdateStats();
}
/// <summary>
/// 重置统计信息
/// </summary>
public void ResetStatistics()
{
ResetStats();
}
/// <summary>
/// 获取当前统计更新间隔
/// </summary>
/// <returns>统计更新间隔(毫秒)</returns>
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
/// </summary>
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<Dictionary<string, object>>() ?? new Dictionary<string, object>();
// 创建LTELog对象
var log = JsonConvert.DeserializeObject<LTELog>(logObj.ToString()); //new LTELog(logData);
// 处理消息和数据
if (log.Data is List<string> dataList && dataList.Count > 0)
try
{
log.Message = dataList[0];
dataList.RemoveAt(0);
}
// 使用JsonConvert反序列化创建LTELog对象
var log = JsonConvert.DeserializeObject<LTELog>(logObj.ToString());
if (log == null) continue;
// 设置方向
log.Direction = _client.DirConvert(log);
// 处理消息和数据 - 从data中提取第一条作为Message(与JavaScript版本保持一致)
if (log.Data is List<string> 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<string> data)
{
var signalRecord = new Dictionary<string, object>();
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<string> data)
{
//log.SignalRecord = signalRecord;
_client.HasSignalRecord = true;
var signalRecord = new Dictionary<string, object>();
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 统计更新相关方法
/// <summary>
/// 设置刷新延迟时间
/// </summary>
/// <param name="delay">延迟时间(毫秒)</param>
public void SetRefreshDelay(int delay)
{
_statsPollDelay = delay;
}
/// <summary>
/// 获取刷新延迟时间
/// </summary>
/// <returns>延迟时间(毫秒)</returns>
public int GetRefreshDelay()
{
return _statsPollDelay;
}
/// <summary>
/// 更新统计信息(对应JavaScript版本的_updateStats)
/// </summary>
/// <param name="first">是否为第一次更新</param>
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();
});
}
/// <summary>
/// 准备统计消息
/// </summary>
/// <param name="msg">统计消息</param>
private void PrepareStatsMessage(JObject msg)
{
// 这里可以添加统计消息的准备工作
// 对应JavaScript版本中的tab.statsPrepare(msg)
_logger.LogDebug($"[{_config.Name}] 准备统计消息: {msg}");
}
/// <summary>
/// 重置统计信息(对应JavaScript版本的_resetStats)
/// </summary>
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}] 重置统计信息");
}
/// <summary>
/// 添加统计到面板
/// </summary>
/// <param name="stats">统计信息</param>
private void AddStatsToPanel(JObject stats)
{
// 这里应该将统计信息添加到统计面板
// 对应JavaScript版本中的lteStatsTab.add(this.getName(), resp)
_logger.LogDebug($"[{_config.Name}] 添加统计到面板: {stats}");
// 可以在这里实现具体的统计面板更新逻辑
// 或者通过事件通知其他组件更新统计信息
}
/// <summary>
/// 启动统计更新定时器
/// </summary>
private void StartStatsTimer()
{
if (_statsTimer != null)
{
_statsTimer.Dispose();
}
_statsTimer = new Timer(_ => UpdateStats(), null, _statsPollDelay, Timeout.Infinite);
}
/// <summary>
/// 停止统计更新定时器
/// </summary>
private void StopStatsTimer()
{
_statsTimer?.Dispose();
_statsTimer = null;
}
#endregion
#endregion
#region IDisposable

Loading…
Cancel
Save