Attempt to handle false "ended" events with mkv files in Chrome due to blob bug
This commit is contained in:
99
server.ts
99
server.ts
@@ -27,6 +27,7 @@ interface ChatMessage {
|
||||
|
||||
// --- Room Management ---
|
||||
const rooms = new Map<string, RoomState>();
|
||||
const pendingDisconnects = new Map<string, ReturnType<typeof setTimeout>>(); // key: "roomCode:username"
|
||||
|
||||
function generateRoomCode(): string {
|
||||
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // no ambiguous chars
|
||||
@@ -348,6 +349,64 @@ const server = Bun.serve<WSData>({
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "rejoin_room": {
|
||||
const username = (msg.username || "").trim();
|
||||
const code = (msg.code || "").trim().toUpperCase();
|
||||
if (!username || !code) {
|
||||
ws.send(JSON.stringify({ type: "error", message: "Username and room code required" }));
|
||||
return;
|
||||
}
|
||||
|
||||
const room = rooms.get(code);
|
||||
if (!room) {
|
||||
ws.send(JSON.stringify({ type: "error", message: "Room no longer exists" }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel any pending disconnect timer for this user
|
||||
const disconnectKey = `${code}:${username}`;
|
||||
const pendingTimer = pendingDisconnects.get(disconnectKey);
|
||||
if (pendingTimer) {
|
||||
clearTimeout(pendingTimer);
|
||||
pendingDisconnects.delete(disconnectKey);
|
||||
console.log(`[Room ${code}] ${username} reconnected (cancelled disconnect timer)`);
|
||||
}
|
||||
|
||||
// Swap in the new WebSocket
|
||||
ws.data.username = username;
|
||||
ws.data.roomCode = code;
|
||||
room.users.set(username, ws as unknown as WebSocket);
|
||||
|
||||
// Send full current state to the reconnected client
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "room_rejoined",
|
||||
code,
|
||||
fileInfo: room.fileInfo,
|
||||
users: getUserList(room),
|
||||
state: {
|
||||
playing: room.playing,
|
||||
position: getCurrentPosition(room),
|
||||
speed: room.speed,
|
||||
},
|
||||
chatHistory: room.chatHistory.slice(-50),
|
||||
})
|
||||
);
|
||||
|
||||
// Notify others that user is back
|
||||
broadcastToRoom(
|
||||
room,
|
||||
{
|
||||
type: "user_rejoined",
|
||||
username,
|
||||
users: getUserList(room),
|
||||
},
|
||||
ws as unknown as WebSocket
|
||||
);
|
||||
console.log(`[Room ${code}] ${username} rejoined`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -358,19 +417,35 @@ const server = Bun.serve<WSData>({
|
||||
const room = rooms.get(roomCode);
|
||||
if (!room) return;
|
||||
|
||||
room.users.delete(username);
|
||||
console.log(`[Room ${roomCode}] ${username} left`);
|
||||
// Don't remove immediately — give a 30s grace period for reconnection
|
||||
const disconnectKey = `${roomCode}:${username}`;
|
||||
console.log(`[Room ${roomCode}] ${username} disconnected (waiting 30s for reconnect)`);
|
||||
|
||||
if (room.users.size === 0) {
|
||||
rooms.delete(roomCode);
|
||||
console.log(`[Room ${roomCode}] Deleted (empty)`);
|
||||
} else {
|
||||
broadcastToRoom(room, {
|
||||
type: "user_left",
|
||||
username,
|
||||
users: getUserList(room),
|
||||
});
|
||||
}
|
||||
const timer = setTimeout(() => {
|
||||
pendingDisconnects.delete(disconnectKey);
|
||||
const currentRoom = rooms.get(roomCode);
|
||||
if (!currentRoom) return;
|
||||
|
||||
// Only remove if the stored WS is still the old one (not swapped by rejoin)
|
||||
const currentWs = currentRoom.users.get(username);
|
||||
if (currentWs === (ws as unknown as WebSocket)) {
|
||||
currentRoom.users.delete(username);
|
||||
console.log(`[Room ${roomCode}] ${username} removed (grace period expired)`);
|
||||
|
||||
if (currentRoom.users.size === 0) {
|
||||
rooms.delete(roomCode);
|
||||
console.log(`[Room ${roomCode}] Deleted (empty)`);
|
||||
} else {
|
||||
broadcastToRoom(currentRoom, {
|
||||
type: "user_left",
|
||||
username,
|
||||
users: getUserList(currentRoom),
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 30_000);
|
||||
|
||||
pendingDisconnects.set(disconnectKey, timer);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user