using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using LTEMvcApp.Models; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System.Text; namespace LTEMvcApp.Services { /// /// 统计服务 - 管理统计数据的队列和SSE推送 /// public class StatisticsService { private readonly ILogger _logger; private readonly StatisticsQueueManager _statsQueue; private readonly ConcurrentDictionary _latestStatsByClient; private readonly ConcurrentDictionary> _statsHistoryByClient; private readonly int _maxHistorySize = 100; // 每个客户端最多保存100条历史记录 /// /// 统计数据更新事件 /// public event EventHandler? StatsUpdated; /// /// 构造函数 /// public StatisticsService(ILogger logger) { _logger = logger; _statsQueue = new StatisticsQueueManager(); _latestStatsByClient = new ConcurrentDictionary(); _statsHistoryByClient = new ConcurrentDictionary>(); _logger.LogInformation("StatisticsService 初始化完成"); } /// /// 处理接收到的统计数据 /// public void ProcessStatsData(JObject data, string clientName) { try { var statsData = StatisticsData.FromJObject(data, clientName); // 添加到队列 _statsQueue.EnqueueStats(statsData); // 更新最新统计数据 _latestStatsByClient[clientName] = statsData; // 添加到历史记录 AddToHistory(clientName, statsData); // 触发事件 StatsUpdated?.Invoke(this, statsData); _logger.LogDebug($"处理统计数据: 客户端 {clientName}, 消息ID {statsData.MessageId}, 小区数量 {statsData.Cells.Count}"); } catch (Exception ex) { _logger.LogError(ex, $"处理统计数据时出错: 客户端 {clientName}"); } } /// /// 添加统计数据到历史记录 /// private void AddToHistory(string clientName, StatisticsData statsData) { if (!_statsHistoryByClient.TryGetValue(clientName, out var history)) { history = new List(); _statsHistoryByClient[clientName] = history; } lock (history) { history.Add(statsData); // 维持历史记录大小 while (history.Count > _maxHistorySize) { history.RemoveAt(0); } } } /// /// 获取所有统计数据 /// public List GetAllStats() { return _statsQueue.GetAllStats(); } /// /// 获取最新的统计数据 /// public StatisticsData? GetLatestStats() { return _statsQueue.GetLatestStats(); } /// /// 获取指定客户端的最新统计数据 /// public StatisticsData? GetLatestStatsByClient(string clientName) { _latestStatsByClient.TryGetValue(clientName, out var stats); return stats; } /// /// 获取指定客户端的历史统计数据 /// public List GetStatsHistoryByClient(string clientName) { _statsHistoryByClient.TryGetValue(clientName, out var history); return history ?? new List(); } /// /// 获取所有客户端的最新统计数据 /// public Dictionary GetAllLatestStats() { return _latestStatsByClient.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } /// /// 清空统计数据 /// public void ClearStats() { _statsQueue.Clear(); _latestStatsByClient.Clear(); _statsHistoryByClient.Clear(); _logger.LogInformation("统计数据已清空"); } /// /// 获取统计摘要信息 /// public object GetSummary() { var summary = new { TotalStatsCount = _statsQueue.Count, ClientCount = _latestStatsByClient.Count, Clients = _latestStatsByClient.Keys.ToList(), LastUpdateTime = _latestStatsByClient.Values .OrderByDescending(s => s.ReceivedAt) .FirstOrDefault()?.ReceivedAt }; return summary; } /// /// 获取SSE格式的统计数据 /// public string GetStatsAsSSE() { var latestStats = GetAllLatestStats(); var sseData = new { type = "stats_update", timestamp = DateTime.UtcNow, data = latestStats }; var json = System.Text.Json.JsonSerializer.Serialize(sseData, new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase }); return $"data: {json}\n\n"; } /// /// 获取指定客户端的SSE格式统计数据 /// public string GetClientStatsAsSSE(string clientName) { var stats = GetLatestStatsByClient(clientName); if (stats == null) { return $"data: {System.Text.Json.JsonSerializer.Serialize(new { type = "error", message = "Client not found" })}\n\n"; } var sseData = new { type = "client_stats_update", clientName = clientName, timestamp = DateTime.UtcNow, data = stats }; var json = System.Text.Json.JsonSerializer.Serialize(sseData, new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase }); return $"data: {json}\n\n"; } /// /// 获取队列大小 /// public int GetQueueCount() { return _statsQueue.Count; } /// /// 获取客户端数量 /// public int GetClientCount() { return _latestStatsByClient.Count; } } }