fix(multi): prevent host pruning and increase timeout to 90s
- Exempt host from inactivity pruning to prevent room corruption - Increase player timeout from 45s to 90s for slower connections - Reduce heartbeat interval from 20s to 15s for better coverage - Refresh all players' lastSeen on nextRound/resetGame to avoid immediate pruning
This commit is contained in:
@@ -47,12 +47,12 @@ function generatePlayerId(): string {
|
|||||||
return crypto.randomUUID();
|
return crypto.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout joueur inactif : 45s (heartbeat toutes les 2s, on laisse large pour les tabs en arrière-plan)
|
// Timeout joueur inactif : 90s (heartbeat toutes les 15s, x6 de marge pour les connexions lentes)
|
||||||
const PLAYER_TIMEOUT_MS = 45_000;
|
const PLAYER_TIMEOUT_MS = 90_000;
|
||||||
|
|
||||||
function prunePlayers(players: Player[]): Player[] {
|
function prunePlayers(players: Player[]): Player[] {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
return players.filter((p) => now - p.lastSeen < PLAYER_TIMEOUT_MS);
|
return players.filter((p) => p.isHost || now - p.lastSeen < PLAYER_TIMEOUT_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcule les points d'un joueur selon ses clics et son temps
|
// Calcule les points d'un joueur selon ses clics et son temps
|
||||||
@@ -455,11 +455,13 @@ export async function PATCH(
|
|||||||
room.roundWinner = null;
|
room.roundWinner = null;
|
||||||
room.countdownStart = null;
|
room.countdownStart = null;
|
||||||
room.roundStart = null;
|
room.roundStart = null;
|
||||||
|
const now = Date.now();
|
||||||
for (const p of room.players) {
|
for (const p of room.players) {
|
||||||
p.hasWon = false;
|
p.hasWon = false;
|
||||||
p.hasSurrendered = false;
|
p.hasSurrendered = false;
|
||||||
p.currentArticle = "";
|
p.currentArticle = "";
|
||||||
p.wonAt = null;
|
p.wonAt = null;
|
||||||
|
p.lastSeen = now; // rafraîchit tous les joueurs pour éviter le pruning immédiat
|
||||||
}
|
}
|
||||||
await saveRoom(room);
|
await saveRoom(room);
|
||||||
return Response.json({ room });
|
return Response.json({ room });
|
||||||
@@ -479,12 +481,14 @@ export async function PATCH(
|
|||||||
room.roundWinner = null;
|
room.roundWinner = null;
|
||||||
room.countdownStart = null;
|
room.countdownStart = null;
|
||||||
room.roundStart = null;
|
room.roundStart = null;
|
||||||
|
const nowReset = Date.now();
|
||||||
for (const p of room.players) {
|
for (const p of room.players) {
|
||||||
p.score = 0;
|
p.score = 0;
|
||||||
p.hasWon = false;
|
p.hasWon = false;
|
||||||
p.hasSurrendered = false;
|
p.hasSurrendered = false;
|
||||||
p.currentArticle = "";
|
p.currentArticle = "";
|
||||||
p.wonAt = null;
|
p.wonAt = null;
|
||||||
|
p.lastSeen = nowReset; // rafraîchit tous les joueurs pour éviter le pruning immédiat
|
||||||
}
|
}
|
||||||
await saveRoom(room);
|
await saveRoom(room);
|
||||||
return Response.json({ room });
|
return Response.json({ room });
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ export function useGameEffects({
|
|||||||
multi.restore(saved.multiRoomCode, saved.multiPlayerId).then((ok) => {
|
multi.restore(saved.multiRoomCode, saved.multiPlayerId).then((ok) => {
|
||||||
// si une nouvelle room a été rejointe pendant le restore, on laisse
|
// si une nouvelle room a été rejointe pendant le restore, on laisse
|
||||||
const current = loadSession();
|
const current = loadSession();
|
||||||
if (current?.multiRoomCode && current.multiRoomCode !== savedCode) return;
|
if (current?.multiRoomCode && current.multiRoomCode !== savedCode)
|
||||||
|
return;
|
||||||
if (ok) setScreen("lobby");
|
if (ok) setScreen("lobby");
|
||||||
else {
|
else {
|
||||||
clearSession();
|
clearSession();
|
||||||
|
|||||||
+1
-1
@@ -116,7 +116,7 @@ export function useMultiGame() {
|
|||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ action: "heartbeat", playerId: ssePidRef.current }),
|
body: JSON.stringify({ action: "heartbeat", playerId: ssePidRef.current }),
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
}, 20_000);
|
}, 15_000);
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user