Files
battleship/data/app.js
T

74 lines
2.5 KiB
JavaScript

(() => {
const target = document.querySelector('#health');
const role = new URLSearchParams(location.search).get('role') || 'spectator';
let socket;
let retryIndex = 0;
let retryTimer;
let pollTimer;
const labels = {
uptime_ms: 'Время работы (мс)', wifi_state: 'Wi-Fi', rssi_dbm: 'RSSI (дБм)',
free_heap_bytes: 'Свободная память (байт)', min_free_heap_bytes: 'Мин. свободная память (байт)',
build_version: 'Версия сборки'
};
function render(health) {
target.replaceChildren();
for (const [key, label] of Object.entries(labels)) {
const term = document.createElement('dt');
const value = document.createElement('dd');
term.textContent = label;
value.textContent = health[key] ?? 'недоступно';
target.append(term, value);
}
}
async function refresh() {
try {
const response = await fetch('/api/health', { cache: 'no-store' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
render(await response.json());
} catch (error) {
target.textContent = `Не удалось получить состояние: ${error.message}`;
}
}
async function pollState() {
try {
const response = await fetch(`/api/state?role=${encodeURIComponent(role)}`, { cache: 'no-store' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const state = await response.json();
document.title = `Морской бой — версия ${state.version}`;
} catch (_) {}
}
function beginPolling() {
if (!pollTimer) pollTimer = window.setInterval(pollState, 2000);
pollState();
}
function stopPolling() {
if (pollTimer) window.clearInterval(pollTimer);
pollTimer = undefined;
}
function connectSocket() {
socket = new WebSocket(`ws://${location.host}/ws?role=${encodeURIComponent(role)}`);
socket.onopen = () => { retryIndex = 0; stopPolling(); };
socket.onmessage = event => {
const state = JSON.parse(event.data);
document.title = `Морской бой — версия ${state.version}`;
};
socket.onclose = () => {
beginPolling();
const delays = [1000, 2000, 5000, 10000];
const delay = delays[Math.min(retryIndex++, delays.length - 1)];
retryTimer = window.setTimeout(connectSocket, delay);
};
socket.onerror = () => socket.close();
}
refresh();
window.setInterval(refresh, 5000);
connectSocket();
})();