fea:Add an elegant exit room feature for the recipient

This commit is contained in:
david_bai
2025-08-10 23:16:59 +08:00
parent 3e6c9b46e8
commit 12cda8c030
8 changed files with 162 additions and 26 deletions
+41 -1
View File
@@ -29,6 +29,11 @@ interface CheckRoomRequest {
roomId: string;
}
interface LeaveRoomRequest {
roomId: string;
socketId: string;
}
// Route handler for creating a room
const createRoomHandler: RequestHandler<{}, any, CreateRoomRequest> = async (
req,
@@ -110,7 +115,7 @@ const setTrackHandler: RequestHandler<{}, any, ReferrerTrack> = async (
// Use MULTI to ensure atomicity of hincrby and expire
await redis
.multi()
.hincrby(dailyKey, ref, 1) // \"referrers:daily:2024-01-20\" : { \"producthunt\": \"5\", \"twitter\": \"3\" }
.hincrby(dailyKey, ref, 1) // "referrers:daily:2024-01-20" : { "producthunt": "5", "twitter": "3" }
.expire(dailyKey, thirtyDaysInSeconds) // Set a 30-day expiration
.exec();
@@ -136,11 +141,46 @@ const logsDebugHandler: RequestHandler<{}, any, LogMessage> = async (
}
};
// Route handler for leaving a room
const leaveRoomHandler: RequestHandler<{}, any, LeaveRoomRequest> = async (
req,
res
) => {
const { roomId, socketId } = req.body;
if (!roomId || !socketId) {
res.status(400).json({ error: "Room ID and Socket ID are required" });
return;
}
try {
const roomExists = await roomService.isRoomExist(roomId);
if (!roomExists) {
res.json({ success: true, message: "Room does not exist." });
return;
}
await roomService.unbindSocketFromRoom(socketId, roomId);
if (await roomService.isRoomEmpty(roomId)) {
await roomService.refreshRoom(roomId, 900); // 15 minutes
console.log(
`Room ${roomId} is empty after leave and will be deleted in 15 min.`
);
}
res.json({ success: true, message: "Successfully left the room" });
} catch (error) {
console.error("Error leaving room:", error);
res.status(500).json({ error: "Internal server error" });
}
};
// Register routes
router.post("/api/create_room", createRoomHandler);
router.get("/api/get_room", getRoomHandler);
router.post("/api/check_room", checkRoomHandler);
router.post("/api/set_track", setTrackHandler);
router.post("/api/logs_debug", logsDebugHandler);
router.post("/api/leave_room", leaveRoomHandler);
export default router;
+4 -4
View File
@@ -115,16 +115,16 @@ export function setupSocketHandlers(io: Server): void {
console.log("Disconnected:", socket.id);
const roomId = await roomService.getRoomBySocketId(socket.id);
if (roomId) {
// Notify other users in the room that this peer has left
socket.to(roomId).emit("peer-disconnected", { peerId: socket.id });
await roomService.unbindSocketFromRoom(socket.id, roomId);
if (await roomService.isRoomEmpty(roomId)) {
// await deleteRoom(roomId);
await roomService.refreshRoom(roomId, 3600);
await roomService.refreshRoom(roomId, 900);
console.log(
`Room ${roomId} is empty and will be deleted in 1 hour due to disconnect.`
`Room ${roomId} is empty and will be deleted in 15 min due to disconnect.`
);
}
// Notify other users in the room that this peer has left
// io.to(roomId).emit('peer-disconnected', { peerId: socket.id });
}
});
});