/** Serve the game state of any valid game id, but block until * the client is no longer blocked (long-polling). */ app.get('/:gameid/longpoll', (req, res) => { const userid = getUserId(req, res); const game = games[parseInt(req.params['gameid'])] if (game == undefined) { res.status(404).json("no such game"); } else { if (isWaiting(game, userid)) { console.log(`Game ${game.id} directly joined by ${userid}`) join(game, userid) res.json(toJson(game, userid)) res.end() return } // Check if userid needs to wait, then either: // - stash the [response, userid] pair for later // - instantly return actionable state if (shouldBlockRequest(game, userid)) { console.log(`Stash long-poll request for ${game.id} by ${userid}`) longpolls[game.id] ??= [] longpolls[game.id].push([res, userid]) // do not end here but keep request hanging. } else { // User can act on the state, no point in waiting. res.json(toJson(game, userid)) res.end() } } })