diff --git a/LTEMvcApp/Controllers/WebSocketController.cs b/LTEMvcApp/Controllers/WebSocketController.cs index 01d2a88..8cc1752 100644 --- a/LTEMvcApp/Controllers/WebSocketController.cs +++ b/LTEMvcApp/Controllers/WebSocketController.cs @@ -460,7 +460,12 @@ namespace LTEMvcApp.Controllers var json = Newtonsoft.Json.JsonConvert.SerializeObject(data); var eventData = $"event: {eventName}\ndata: {json}\n\n"; + _logger.LogDebug("SendSseEvent: 发送事件 {EventName}, 数据长度: {DataLength}, 事件数据长度: {EventDataLength}", + eventName, json.Length, eventData.Length); + await Response.WriteAsync(eventData); + + _logger.LogDebug("SendSseEvent: 事件 {EventName} 发送成功", eventName); } catch (Exception ex) { @@ -706,13 +711,24 @@ namespace LTEMvcApp.Controllers if (hasNewLogs && newLogs.Any()) { _logger.LogInformation("StreamLogs: 发送新日志事件,新增日志数量: {NewCount}, 总日志数量: {TotalCount}", newLogs.Count, currentLogs.Count); - await SendSseEvent("new_logs", new { + _logger.LogDebug("StreamLogs: 新日志详情 - 第一条: {FirstLog}, 最后一条: {LastLog}", + newLogs.FirstOrDefault()?.Message, + newLogs.LastOrDefault()?.Message); + + var eventData = new { logs = newLogs, totalCount = currentLogs.Count, newCount = newLogs.Count - }); + }; + + _logger.LogDebug("StreamLogs: 准备发送事件数据: {EventData}", + Newtonsoft.Json.JsonConvert.SerializeObject(eventData)); + + await SendSseEvent("new_logs", eventData); await Response.Body.FlushAsync(cancellationToken); + _logger.LogInformation("StreamLogs: 新日志事件发送完成"); + // 更新索引和缓存 lastLogCount = currentLogs.Count; lastLogs = currentLogs.ToList(); @@ -1052,6 +1068,41 @@ namespace LTEMvcApp.Controllers return StatusCode(500, new { message = "获取调试信息失败", error = ex.Message }); } } + + /// + /// 获取SSE连接状态(调试用) + /// + /// 连接状态信息 + [HttpGet("logs/connection-status")] + public ActionResult GetSseConnectionStatus() + { + try + { + var status = new + { + timestamp = DateTime.UtcNow, + requestHeaders = Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()), + userAgent = Request.Headers["User-Agent"].ToString(), + accept = Request.Headers["Accept"].ToString(), + cacheControl = Request.Headers["Cache-Control"].ToString(), + connection = Request.Headers["Connection"].ToString(), + isHttps = Request.IsHttps, + host = Request.Host.ToString(), + path = Request.Path.ToString(), + queryString = Request.QueryString.ToString(), + method = Request.Method, + contentType = Request.ContentType, + contentLength = Request.ContentLength + }; + + return Ok(status); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取SSE连接状态时发生错误"); + return StatusCode(500, new { message = "获取连接状态失败", error = ex.Message }); + } + } } /// diff --git a/LTEMvcApp/Views/Home/Logs.cshtml b/LTEMvcApp/Views/Home/Logs.cshtml index e4bca63..a6f2ca7 100644 --- a/LTEMvcApp/Views/Home/Logs.cshtml +++ b/LTEMvcApp/Views/Home/Logs.cshtml @@ -538,6 +538,7 @@ +
@@ -622,6 +623,7 @@ const addTestDataBtn = document.getElementById('add-test-data-btn'); const reconnectBtn = document.getElementById('reconnect-btn'); const debugBtn = document.getElementById('debug-btn'); + const testConnectionBtn = document.getElementById('test-connection-btn'); const logListPanel = document.querySelector('.log-list-panel'); const resizer = document.getElementById('drag-resizer'); const layerFilterOptions = document.getElementById('layer-filter-options'); @@ -1072,6 +1074,12 @@ eventSource = new EventSource('/api/websocket/logs/stream'); + // 添加连接打开事件监听 + eventSource.onopen = function(event) { + console.log('EventSource onopen 事件:', event); + updateConnectionStatus('connected', '已连接'); + }; + eventSource.addEventListener('connected', function(event) { console.log("SSE连接已建立", event); updateConnectionStatus('connected', '已连接'); @@ -1081,6 +1089,7 @@ eventSource.addEventListener('history', function(event) { console.log("接收到历史日志事件", event); + console.log("历史日志原始数据:", event.data); try { const data = JSON.parse(event.data); console.log("历史日志数据:", data); @@ -1093,12 +1102,14 @@ } } catch (error) { console.error("解析历史日志数据失败:", error); + console.error("原始数据:", event.data); showError("解析历史日志数据失败: " + error.message); } }); eventSource.addEventListener('new_logs', function(event) { console.log("接收到新日志事件", event); + console.log("新日志原始数据:", event.data); try { const data = JSON.parse(event.data); console.log("新日志数据:", data); @@ -1110,6 +1121,7 @@ } } catch (error) { console.error("解析新日志数据失败:", error); + console.error("原始数据:", event.data); showError("解析新日志数据失败: " + error.message); } }); @@ -1158,6 +1170,7 @@ eventSource.onerror = function (err) { console.error("SSE 连接错误:", err); + console.error("EventSource readyState:", eventSource.readyState); updateConnectionStatus('error', '连接失败'); // 自动重连 @@ -1272,10 +1285,12 @@ sortField: sortField, sortDirection: sortDirection, columnVisibility: columnVisibility, - clusterizeRows: clusterize.rows.length + clusterizeRows: clusterize.rows.length, + url: window.location.href, + userAgent: navigator.userAgent }; - console.log('调试信息:', debugInfo); + console.log('前端调试信息:', debugInfo); // 检查服务器端日志缓存状态 fetch('/api/websocket/logs/debug') @@ -1288,6 +1303,30 @@ console.error('获取服务器调试信息失败:', error); showError('获取服务器调试信息失败: ' + error.message); }); + + // 检查SSE连接状态 + fetch('/api/websocket/logs/connection-status') + .then(response => response.json()) + .then(data => { + console.log('SSE连接状态:', data); + }) + .catch(error => { + console.error('获取SSE连接状态失败:', error); + }); + }); + + testConnectionBtn.addEventListener('click', function() { + // 测试连接 + fetch('/api/websocket/logs/test-connection') + .then(response => response.json()) + .then(data => { + if (data.message) { + showInfo(data.message); + } + }) + .catch(error => { + showError('测试连接失败: ' + error.message); + }); }); // --- Resizer Logic ---