36 lines
1.3 KiB
JavaScript
36 lines
1.3 KiB
JavaScript
import { state } from './state.js';
|
|
|
|
let ws;
|
|
let reconnectAttempts = 0;
|
|
let reconnectTimer = null;
|
|
const outbox = [];
|
|
|
|
export function wsIsOpen() { return ws && ws.readyState === WebSocket.OPEN; }
|
|
export function sendMsg(obj) { if (wsIsOpen()) ws.send(JSON.stringify(obj)); else outbox.push(obj); }
|
|
|
|
function scheduleReconnect(connect) {
|
|
if (reconnectTimer) return;
|
|
const delay = Math.min(30000, 1000 * Math.pow(2, reconnectAttempts));
|
|
reconnectAttempts++;
|
|
reconnectTimer = setTimeout(() => { reconnectTimer = null; connect(); }, delay);
|
|
}
|
|
|
|
export function connectWS(onMessage) {
|
|
const url = (location.protocol === 'https:' ? 'wss://' : 'ws://') + location.host;
|
|
ws = new WebSocket(url);
|
|
ws.addEventListener('open', () => {
|
|
reconnectAttempts = 0;
|
|
setTimeout(() => { while (outbox.length && wsIsOpen()) { try { ws.send(JSON.stringify(outbox.shift())); } catch { break; } } }, 100);
|
|
});
|
|
ws.addEventListener('message', (ev) => onMessage(ev));
|
|
ws.addEventListener('close', () => { scheduleReconnect(() => connectWS(onMessage)); });
|
|
ws.addEventListener('error', () => { try { ws.close(); } catch {} });
|
|
}
|
|
|
|
window.addEventListener('online', () => {
|
|
if (!wsIsOpen()) {
|
|
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
|
// Kick off a reconnect by calling connectWS from app main again
|
|
}
|
|
});
|