Websockets instead of polling
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
let state = null;
|
||||
let error = '';
|
||||
let intervalId;
|
||||
let ws = null;
|
||||
let reconnectTimer = null;
|
||||
let reconnectDelay = 1000;
|
||||
let destroyed = false;
|
||||
|
||||
async function fetchState() {
|
||||
try {
|
||||
@@ -29,10 +33,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
// The server pushes a ping over this socket whenever the game changes;
|
||||
// each ping triggers a refetch of the state blob.
|
||||
function connectSocket() {
|
||||
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
ws = new WebSocket(`${proto}://${location.host}/api/game/${gameId}/ws`);
|
||||
ws.onopen = () => {
|
||||
reconnectDelay = 1000;
|
||||
fetchState(); // catch up on anything missed while disconnected
|
||||
};
|
||||
ws.onmessage = () => fetchState();
|
||||
ws.onclose = () => {
|
||||
if (destroyed) return;
|
||||
reconnectTimer = setTimeout(connectSocket, reconnectDelay);
|
||||
reconnectDelay = Math.min(reconnectDelay * 2, 10000);
|
||||
};
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
fetchState();
|
||||
// Poll every 2 seconds
|
||||
intervalId = setInterval(fetchState, 2000);
|
||||
connectSocket();
|
||||
// Slow fallback poll in case a push is ever missed
|
||||
intervalId = setInterval(fetchState, 30000);
|
||||
});
|
||||
|
||||
// Surface the creator-only Admin link in the corner menu
|
||||
@@ -43,7 +65,10 @@
|
||||
);
|
||||
|
||||
onDestroy(() => {
|
||||
destroyed = true;
|
||||
if (intervalId) clearInterval(intervalId);
|
||||
if (reconnectTimer) clearTimeout(reconnectTimer);
|
||||
if (ws) ws.close();
|
||||
extraMenuLinks.set([]);
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user