From 8a9e0efed3b3bf29ba2e7ea4de7460ebe9ba40fa Mon Sep 17 00:00:00 2001 From: Tot Maxim Date: Sat, 9 May 2026 12:21:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/server/web/js/app.js | 55 +++++++++++++++++++++++++++++++++----- cmd/server/web/js/chart.js | 17 ++++++------ 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/cmd/server/web/js/app.js b/cmd/server/web/js/app.js index b8c8471..5849b15 100644 --- a/cmd/server/web/js/app.js +++ b/cmd/server/web/js/app.js @@ -15,6 +15,9 @@ import { drawChart } from "./chart.js"; let lastChart = 0; let connectionLost = false; +let consecutiveErrors = 0; // счётчик ошибок подряд +const MAX_ERRORS = 3; // после скольки ошибок замедляем опрос +let pollTimer = null; // храним ID таймера для возможности сброса // ================= INIT ================= window.addEventListener("DOMContentLoaded", () => { @@ -30,6 +33,12 @@ async function update() { fetchHistory() ]); + consecutiveErrors = 0; + + if (connectionLost) { + console.log("[app] Соединение восстановлено"); + } + // ===== STATUS ===== const isOnline = h.pipe_alive && h.has_data; @@ -37,7 +46,7 @@ async function update() { setStatus("На связи"); connectionLost = false; } else { - setStatus("Нет связи", true); // true = lost connection + setStatus("Нет связи", true); connectionLost = true; } @@ -57,9 +66,8 @@ async function update() { setBars(smooth(percent)); setSignal(level); } else { - // При потере связи - сбрасываем индикаторы - setBars(0, true); // true = no connection - setSignal(0, true); // true = no connection + setBars(0, true); + setSignal(0, true); } if (DOM.lastByte) { @@ -95,7 +103,12 @@ async function update() { } } catch (e) { - console.error("UPDATE ERROR:", e); + consecutiveErrors++; + + if (consecutiveErrors === 1) { + console.warn("[app] Сервер недоступен, ждём..."); + } + setStatus("СЕРВЕР НЕДОСТУПЕН", true); setBars(0, true); setSignal(0, true); @@ -103,9 +116,37 @@ async function update() { if (DOM.lastByte) { DOM.lastByte.textContent = "--"; } + + if (consecutiveErrors >= MAX_ERRORS) { + clearInterval(pollTimer); + pollTimer = setInterval(update, 2000); + console.log("[app] Замедлили опрос до 2с"); + } } } -// ================= LOOP ================= -setInterval(update, 500); +// ================= RECONNECT LOGIC ================= +function startPolling() { + if (pollTimer) clearInterval(pollTimer); + + // Если были ошибки — сразу пробуем переподключиться + if (consecutiveErrors > 0) { + console.log("[app] Попытка переподключения..."); + update(); + } + + pollTimer = setInterval(update, 500); +} + +// Сброс при фокусе окна (пользователь вернулся — пробуем быстро) +window.addEventListener("focus", () => { + if (consecutiveErrors >= MAX_ERRORS) { + console.log("[app] Окно в фокусе, ускоряем опрос"); + consecutiveErrors = 0; + startPolling(); + } +}); + +// ================= START ================= +startPolling(); update(); \ No newline at end of file diff --git a/cmd/server/web/js/chart.js b/cmd/server/web/js/chart.js index 51c4c21..47b7149 100644 --- a/cmd/server/web/js/chart.js +++ b/cmd/server/web/js/chart.js @@ -1,29 +1,30 @@ // chart.js -let ctx = null; - export function drawChart(canvas, history) { if (!canvas || !history?.length) return; - const ctx = canvas.getContext("2d"); - const rect = canvas.getBoundingClientRect(); - canvas.width = rect.width; - canvas.height = rect.height; + const displayHeight = rect.height || 120; + const displayWidth = rect.width || 800; + + canvas.width = displayWidth; + canvas.height = displayHeight; + const ctx = canvas.getContext("2d"); const w = canvas.width; const h = canvas.height; ctx.clearRect(0, 0, w, h); - const stepX = w / 1000; + const stepX = w / history.length; const scaleY = h / 63; ctx.strokeStyle = "#00ff88"; + ctx.lineWidth = 2; ctx.beginPath(); for (let i = 0; i < history.length; i++) { const x = i * stepX; - const y = h - history[i].value * scaleY; + const y = h - history[i] * scaleY; if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);