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:
@@ -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 5–6 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)
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ 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,
|
||||||
});
|
});
|
||||||
if (!res.ok) throw new Error(await res.text());
|
if (!res.ok) throw new Error(await res.text());
|
||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user