feat: add periodic game.status broadcast and live status REST endpoint

Add 20-second game.status WebSocket heartbeat from active shard monitors
containing full game state, and GET /status-live REST endpoint for on-demand
polling. Fix missing token destructuring in SessionInfo causing crash.
Relax frontend polling from 3s to 60s since WebSocket events now cover
real-time updates. Bump version to 0.6.0.

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-20 21:05:19 -04:00
parent a7bd0650eb
commit 34637d6d2c
8 changed files with 328 additions and 9 deletions

View File

@@ -90,6 +90,38 @@ class EcastShardClient {
this.seq = 0;
this.appTag = null;
this.reconnecting = false;
this.statusInterval = null;
}
getSnapshot() {
return {
sessionId: this.sessionId,
gameId: this.gameId,
roomCode: this.roomCode,
appTag: this.appTag,
maxPlayers: this.maxPlayers,
playerCount: this.playerCount,
players: [...this.playerNames],
lobbyState: this.lobbyState,
gameState: this.gameState,
gameStarted: this.gameStarted,
gameFinished: this.gameFinished,
monitoring: true,
};
}
startStatusBroadcast() {
this.stopStatusBroadcast();
this.statusInterval = setInterval(() => {
this.onEvent('game.status', this.getSnapshot());
}, 20000);
}
stopStatusBroadcast() {
if (this.statusInterval) {
clearInterval(this.statusInterval);
this.statusInterval = null;
}
}
buildReconnectUrl() {
@@ -152,6 +184,8 @@ class EcastShardClient {
lobbyState: this.lobbyState,
gameState: this.gameState,
});
this.startStatusBroadcast();
}
handleEntityUpdate(result) {
@@ -406,6 +440,7 @@ class EcastShardClient {
}
disconnect() {
this.stopStatusBroadcast();
if (this.ws) {
try {
this.ws.close(1000, 'Monitor stopped');
@@ -569,4 +604,9 @@ async function cleanupAllShards() {
console.log('[Shard Monitor] Cleaned up all active shards');
}
module.exports = { EcastShardClient, startMonitor, stopMonitor, cleanupAllShards };
function getMonitorSnapshot(sessionId, gameId) {
const client = activeShards.get(`${sessionId}-${gameId}`);
return client ? client.getSnapshot() : null;
}
module.exports = { EcastShardClient, startMonitor, stopMonitor, cleanupAllShards, getMonitorSnapshot };