iframe optimalization

This commit is contained in:
2026-06-22 14:49:42 +02:00
parent 9d196fcfca
commit c893b5e975
+56 -36
View File
@@ -17,27 +17,41 @@
color: #fff; color: #fff;
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
position: relative;
} }
/* ── NORMAL VIEW ──────────────────────────────── */ /* ── NORMAL VIEW ──────────────────────────────── */
#normal-view { #normal-view {
position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100vh; height: 100vh;
border: none; border: none;
display: block; z-index: 1;
} }
/* ── ALARM VIEW ──────────────────────────────── */ /* ── ALARM VIEW ──────────────────────────────── */
#alarm-view { #alarm-view {
display: none; position: absolute;
flex-direction: column; top: 0;
left: 0;
width: 100%; width: 100%;
height: 100vh; height: 100vh;
background: #0d0000; z-index: 2; /* Warstwa na wierzchu */
overflow: hidden;
} /* Zamiast display: none, używamy przezroczystości i wyłączamy kliknięcia */
#alarm-view.active { opacity: 0;
pointer-events: none;
display: flex; display: flex;
flex-direction: column;
background: #0d0000;
transition: opacity 0.3s ease; /* Łagodne przejście */
}
#alarm-view.active {
opacity: 1;
pointer-events: auto; /* Włączenie interakcji, jeśli potrzebne */
} }
.alarm-header { .alarm-header {
@@ -274,8 +288,8 @@
const DEBUG_MACHINES = ["2.60", "3.22", "4.09"]; const DEBUG_MACHINES = ["2.60", "3.22", "4.09"];
const DEBUG_DATA = { const DEBUG_DATA = {
"2.60": { machine: "2.60", status: "Alarm - brak materiału" }, "2.60": { machine: "2.60", status: "Alarm - brak materiału" },
"3.22": { machine: "3.22", status: "Alarm - awaria" }, 3.22: { machine: "3.22", status: "Alarm - awaria" },
"4.09": { machine: "4.09", status: "Alarm - przekroczony cykl" }, 4.09: { machine: "4.09", status: "Alarm - przekroczony cykl" },
}; };
const machineData = {}; // id → last data payload const machineData = {}; // id → last data payload
@@ -287,6 +301,22 @@
// (nawet przy technicznie otwartym WS), dane uznajemy za nieaktualne. // (nawet przy technicznie otwartym WS), dane uznajemy za nieaktualne.
const DATA_STALE_MS = 2 * 60 * 1000; // 2 minuty const DATA_STALE_MS = 2 * 60 * 1000; // 2 minuty
const iframe = document.getElementById("normal-view");
iframe.onload = () => {
console.log("Iframe załadowany, startuję WebSockety...");
// Dajemy stronie w iframe jeszcze sekundę na przetworzenie własnego JS
setTimeout(() => {
MACHINES.forEach(connect);
}, 1000);
};
setTimeout(() => {
if (Object.keys(wsMap).length === 0) {
MACHINES.forEach(connect);
}
}, 10000);
function resetStaleTimer(id) { function resetStaleTimer(id) {
clearTimeout(dataTimers[id]); clearTimeout(dataTimers[id]);
dataTimers[id] = setTimeout(() => { dataTimers[id] = setTimeout(() => {
@@ -296,8 +326,8 @@
// NOWE: Jeśli dane są przestarzałe, zakładamy, że WebSocket to "zombie". // NOWE: Jeśli dane są przestarzałe, zakładamy, że WebSocket to "zombie".
// Zabijamy go ręcznie, co wywoła onclose i sprowokuje ponowne połączenie. // Zabijamy go ręcznie, co wywoła onclose i sprowokuje ponowne połączenie.
if (wsMap[id] && wsStatus[id] === "connected") { if (wsMap[id] && wsStatus[id] === "connected") {
console.warn(`Brak danych dla ${id} - ubijam ciche połączenie`); console.warn(`Brak danych dla ${id} - ubijam ciche połączenie`);
wsMap[id].close(); wsMap[id].close();
} }
}, DATA_STALE_MS); }, DATA_STALE_MS);
} }
@@ -325,9 +355,9 @@
try { try {
const msg = JSON.parse(ev.data); const msg = JSON.parse(ev.data);
if (msg.data) { if (msg.data) {
machineData[id] = { ...msg.data, _ts: Date.now() }; machineData[id] = { ...msg.data, _ts: Date.now() };
resetStaleTimer(id); resetStaleTimer(id);
updateDisplay(); updateDisplay();
} }
} catch (e) { } catch (e) {
/* ignore malformed frames */ /* ignore malformed frames */
@@ -337,25 +367,20 @@
ws.onerror = () => { ws.onerror = () => {
wsStatus[id] = "error"; wsStatus[id] = "error";
refreshStatus(); refreshStatus();
// NOWE: Jitter zapobiegający "Thundering Herd"
// Baza 5000ms + losowo od 0 do 3000ms
const reconnectDelay = RECONNECT_MS + Math.floor(Math.random() * 3000);
setTimeout(() => connect(id), reconnectDelay);
}; };
ws.onclose = () => { ws.onclose = () => {
wsStatus[id] = "disconnected"; wsStatus[id] = "disconnected";
// Usuwamy dane maszyny przy rozłączeniu - nie możemy potwierdzić clearTimeout(dataTimers[id]);
// aktualnego stanu, więc nie trzymamy przestarzałego alarmu w cache. delete machineData[id];
// Po ponownym połączeniu serwer wyśle aktualny stan. updateDisplay();
clearTimeout(dataTimers[id]); refreshStatus();
delete machineData[id];
updateDisplay(); const reconnectDelay =
refreshStatus(); RECONNECT_MS + Math.floor(Math.random() * 3000);
setTimeout(() => connect(id), RECONNECT_MS); setTimeout(() => connect(id), reconnectDelay);
}; };
} }
// ── Display logic ───────────────────────────────────────────────────────── // ── Display logic ─────────────────────────────────────────────────────────
@@ -373,18 +398,15 @@
.filter(([, d]) => isAlarm(d)) .filter(([, d]) => isAlarm(d))
.sort(([a], [b]) => a.localeCompare(b, undefined, { numeric: true })); .sort(([a], [b]) => a.localeCompare(b, undefined, { numeric: true }));
const normalView = document.getElementById("normal-view");
const alarmView = document.getElementById("alarm-view"); const alarmView = document.getElementById("alarm-view");
const countEl = document.getElementById("alarm-count"); const countEl = document.getElementById("alarm-count");
if (alarms.length > 0) { if (alarms.length > 0) {
normalView.style.display = "none";
alarmView.classList.add("active"); alarmView.classList.add("active");
countEl.textContent = countEl.textContent =
alarms.length === 1 ? "1 maszyna" : alarms.length + " maszyny"; alarms.length === 1 ? "1 maszyna" : alarms.length + " maszyny";
renderCards(alarms); renderCards(alarms);
} else { } else {
normalView.style.display = "block";
alarmView.classList.remove("active"); alarmView.classList.remove("active");
} }
} }
@@ -427,8 +449,6 @@
}); });
document.getElementById("status-bar").textContent = document.getElementById("status-bar").textContent =
"[DEBUG] widok alarmowy"; "[DEBUG] widok alarmowy";
} else {
MACHINES.forEach(connect);
} }
updateDisplay(); updateDisplay();
</script> </script>