Implement dynamic lobby polling with faster refresh rate and prevent concurrent requests

Added faster polling interval (700ms) for pre-game lobby to show joining players in near real-time, while keeping slower 2.5s refresh for active games. Implemented pending request flag to prevent concurrent API calls from overlapping. Added `cache: "no-store"` to fetch configuration to ensure fresh data on every request. Updated useEffect dependency array to re-initialize polling when game start state changes.
This commit is contained in:
2026-08-02 09:22:48 +02:00
parent 1bbbe31500
commit 29e063d88d
2 changed files with 11 additions and 5 deletions
+9 -4
View File
@@ -225,18 +225,23 @@ export default function App() {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [gameId]); }, [gameId]);
// ✅ Live refresh (Members/Meta) damit neue Joiner ohne Reload sichtbar sind // ✅ Live refresh (Members/Meta) Lobby schnell, laufendes Spiel genügsamer.
// Für 56 Spieler reicht 2.5s völlig, ist "live genug" und schont Backend.
useEffect(() => { useEffect(() => {
if (!me || !gameId) return; if (!me || !gameId) return;
let alive = true; let alive = true;
let pending = false;
const refreshInterval = gameMeta?.started ? 2500 : 700;
const tick = async () => { const tick = async () => {
if (pending) return;
pending = true;
try { try {
await loadGameMeta(); // refresh members + winner meta await loadGameMeta(); // refresh members + winner meta
} catch { } catch {
// ignore // ignore
} finally {
pending = false;
} }
}; };
@@ -246,14 +251,14 @@ export default function App() {
const id = setInterval(() => { const id = setInterval(() => {
if (!alive) return; if (!alive) return;
tick(); tick();
}, 2500); }, refreshInterval);
return () => { return () => {
alive = false; alive = false;
clearInterval(id); clearInterval(id);
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [me?.id, gameId]); }, [me?.id, gameId, gameMeta?.started]);
useEffect(() => { useEffect(() => {
// wid kann auch "" sein (kein Sieger) // wid kann auch "" sein (kein Sieger)
+1
View File
@@ -3,6 +3,7 @@ import { API_BASE } from "../constants";
export async function api(path, opts = {}) { export async function api(path, opts = {}) {
const res = await fetch(API_BASE + path, { const res = await fetch(API_BASE + path, {
credentials: "include", credentials: "include",
cache: "no-store",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
...opts, ...opts,
}); });