feat: Enhance WebSocket connection reliability with client-side retry/timeout and faster pings, and disable dashboard caching.
This commit is contained in:
@@ -198,7 +198,7 @@ const interval = setInterval(() => {
|
|||||||
ws.isAlive = false;
|
ws.isAlive = false;
|
||||||
ws.ping();
|
ws.ping();
|
||||||
});
|
});
|
||||||
}, 30000);
|
}, 10000);
|
||||||
|
|
||||||
wss.on('close', () => {
|
wss.on('close', () => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
|||||||
@@ -515,23 +515,60 @@ const dashboardHTML = `<!DOCTYPE html>
|
|||||||
<script>
|
<script>
|
||||||
let devices = {};
|
let devices = {};
|
||||||
let ws;
|
let ws;
|
||||||
|
let retryCount = 0;
|
||||||
|
let connectionTimeout;
|
||||||
|
|
||||||
function connectWebSocket() {
|
function connectWebSocket() {
|
||||||
|
retryCount++;
|
||||||
|
console.log('WebSocket: Connecting... (attempt ' + retryCount + ')');
|
||||||
|
document.getElementById('connection-status').textContent = 'Connecting... (attempt ' + retryCount + ')';
|
||||||
|
|
||||||
|
// Clear any existing connection
|
||||||
|
if (ws) {
|
||||||
|
ws.onclose = null;
|
||||||
|
ws.onerror = null;
|
||||||
|
ws.onopen = null;
|
||||||
|
try { ws.close(); } catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
ws = new WebSocket('ws://' + window.location.host);
|
ws = new WebSocket('ws://' + window.location.host);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('WebSocket: Failed to create', err);
|
||||||
|
setTimeout(connectWebSocket, 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection timeout - abort if no response in 3 seconds
|
||||||
|
connectionTimeout = setTimeout(() => {
|
||||||
|
console.log('WebSocket: Connection timeout, retrying...');
|
||||||
|
if (ws.readyState === WebSocket.CONNECTING) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
|
clearTimeout(connectionTimeout);
|
||||||
|
console.log('WebSocket: Connected');
|
||||||
|
retryCount = 0;
|
||||||
document.getElementById('ws-dot').classList.add('connected');
|
document.getElementById('ws-dot').classList.add('connected');
|
||||||
document.getElementById('connection-status').textContent = 'Connected';
|
document.getElementById('connection-status').textContent = 'Connected';
|
||||||
document.getElementById('connection-status').classList.add('connected');
|
document.getElementById('connection-status').classList.add('connected');
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = () => {
|
ws.onclose = (e) => {
|
||||||
|
clearTimeout(connectionTimeout);
|
||||||
|
console.log('WebSocket: Closed', e.code, e.reason);
|
||||||
document.getElementById('ws-dot').classList.remove('connected');
|
document.getElementById('ws-dot').classList.remove('connected');
|
||||||
document.getElementById('connection-status').textContent = 'Disconnected - Reconnecting...';
|
document.getElementById('connection-status').textContent = 'Disconnected - Reconnecting...';
|
||||||
document.getElementById('connection-status').classList.remove('connected');
|
document.getElementById('connection-status').classList.remove('connected');
|
||||||
setTimeout(connectWebSocket, 2000);
|
setTimeout(connectWebSocket, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ws.onerror = (e) => {
|
||||||
|
console.error('WebSocket: Error', e);
|
||||||
|
};
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
|
|
||||||
@@ -841,7 +878,12 @@ const server = http.createServer(async (req, res) => {
|
|||||||
|
|
||||||
// Serve dashboard
|
// Serve dashboard
|
||||||
if (url.pathname === '/' || url.pathname === '/index.html') {
|
if (url.pathname === '/' || url.pathname === '/index.html') {
|
||||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'text/html',
|
||||||
|
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||||
|
'Pragma': 'no-cache',
|
||||||
|
'Expires': '0'
|
||||||
|
});
|
||||||
res.end(dashboardHTML);
|
res.end(dashboardHTML);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user