refactor(socket.io): complete rewrite to manage dynamic rooms and seeding better
This commit is contained in:
@@ -1,33 +1,16 @@
|
||||
import type { Server as HttpServer } from "node:http";
|
||||
//import { dirname, join } from "node:path";
|
||||
//import { fileURLToPath } from "node:url";
|
||||
import { instrument } from "@socket.io/admin-ui";
|
||||
import { Server } from "socket.io";
|
||||
|
||||
import { createLogger } from "../logger/logger.controller.js";
|
||||
import { auth } from "../utils/auth.utils.js";
|
||||
import { allowedOrigins } from "../utils/cors.utils.js";
|
||||
import { registerEmitter } from "./roomEmitter.socket.js";
|
||||
import {
|
||||
createRoomEmitter,
|
||||
preseedRoom,
|
||||
registerRoomService,
|
||||
} from "./roomService.socket.js";
|
||||
import { registerHasRoomMembers } from "./socket.manager.js";
|
||||
import { isRoomKey, roomConfigs } from "./socket.roomConfig.js";
|
||||
|
||||
//const __filename = fileURLToPath(import.meta.url);
|
||||
//const __dirname = dirname(__filename);
|
||||
const log = createLogger({ module: "socket.io", subModule: "setup" });
|
||||
|
||||
import { auth } from "../utils/auth.utils.js";
|
||||
//import type { Session, User } from "better-auth"; // adjust if needed
|
||||
import { getRoomConfig } from "./roomDefinitions.socket.js";
|
||||
|
||||
// declare module "socket.io" {
|
||||
// interface Socket {
|
||||
// user?: User | any;
|
||||
// session?: Session;
|
||||
// }
|
||||
// }
|
||||
|
||||
export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
|
||||
const io = new Server(server, {
|
||||
path: `${baseUrl}/api/socket.io`,
|
||||
@@ -37,12 +20,16 @@ export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
|
||||
},
|
||||
});
|
||||
|
||||
// manage members of the rooms.
|
||||
registerRoomService(io);
|
||||
registerHasRoomMembers((roomId) => {
|
||||
return (io.sockets.adapter.rooms.get(roomId)?.size ?? 0) > 0;
|
||||
});
|
||||
|
||||
// ✅ Create emitter instance
|
||||
const { addDataToRoom } = createRoomEmitter(io);
|
||||
registerEmitter(addDataToRoom);
|
||||
registerEmitter((roomId, payloads) => {
|
||||
io.to(roomId).emit("room-update", {
|
||||
roomId,
|
||||
payloads,
|
||||
});
|
||||
});
|
||||
|
||||
io.use(async (socket, next) => {
|
||||
try {
|
||||
@@ -85,79 +72,95 @@ export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
// s.on("join-room", async (rn) => {
|
||||
// const config = protectedRooms[rn];
|
||||
s.on("join-room", async ({ room, params }) => {
|
||||
if (!isRoomKey(room)) return;
|
||||
|
||||
// if (config?.requiresAuth && !s.user) {
|
||||
// return s.emit("room-error", {
|
||||
// room: rn,
|
||||
// message: "Authentication required",
|
||||
// });
|
||||
// }
|
||||
|
||||
// const roles = Array.isArray(config?.role) ? config?.role : [config?.role];
|
||||
|
||||
// //if (config?.role && s.user?.role !== config.role) {
|
||||
// if (config?.role && !roles.includes(s.user?.role)) {
|
||||
// return s.emit("room-error", {
|
||||
// roomId: rn,
|
||||
// message: `Not authorized to be in room: ${rn}`,
|
||||
// });
|
||||
// }
|
||||
// s.join(rn);
|
||||
|
||||
// // get room seeded
|
||||
// const history = await preseedRoom(rn);
|
||||
// log.info({}, `User joined ${rn}: ${s.id}`);
|
||||
// // send the intial data
|
||||
// s.emit("room-update", {
|
||||
// roomId: rn,
|
||||
// payloads: history,
|
||||
// initial: true,
|
||||
// });
|
||||
// });
|
||||
|
||||
s.on("join-room", async (rn: string) => {
|
||||
const config = getRoomConfig(rn);
|
||||
const config = roomConfigs[room];
|
||||
|
||||
if (!config) {
|
||||
return s.emit("room-error", {
|
||||
roomId: rn,
|
||||
message: `Unknown room: ${rn}`,
|
||||
roomId: room,
|
||||
message: `Unknown room: ${room}`,
|
||||
});
|
||||
}
|
||||
|
||||
if (config.requiresAuth && !s.user) {
|
||||
const actualRoom = config.buildRoom
|
||||
? config.buildRoom(params)
|
||||
: (room as any);
|
||||
|
||||
const allowed = config.canJoin
|
||||
? await config.canJoin({
|
||||
socket: s,
|
||||
user: s.user,
|
||||
room,
|
||||
actualRoom,
|
||||
params,
|
||||
})
|
||||
: true;
|
||||
|
||||
if (!allowed) {
|
||||
return s.emit("room-error", {
|
||||
roomId: rn,
|
||||
message: "Authentication required",
|
||||
roomId: room,
|
||||
message: `Not authorized to be in room: ${room}`,
|
||||
});
|
||||
}
|
||||
|
||||
const roles = Array.isArray(config.role) ? config.role : [];
|
||||
await s.join(actualRoom);
|
||||
|
||||
if (roles.length > 0 && !roles.includes(s.user?.role)) {
|
||||
return s.emit("room-error", {
|
||||
roomId: rn,
|
||||
message: `Not authorized to be in room: ${rn}`,
|
||||
});
|
||||
}
|
||||
|
||||
s.join(rn);
|
||||
|
||||
const history = await preseedRoom(rn as any);
|
||||
|
||||
log.info({}, `User joined ${rn}: ${s.id}`);
|
||||
|
||||
s.emit("room-update", {
|
||||
roomId: rn,
|
||||
payloads: history,
|
||||
initial: true,
|
||||
s.emit("room-joined", {
|
||||
room,
|
||||
roomId: actualRoom,
|
||||
params,
|
||||
});
|
||||
|
||||
if (config.seed) {
|
||||
const payloads = await config.seed({
|
||||
room,
|
||||
actualRoom,
|
||||
params,
|
||||
user: s.user,
|
||||
});
|
||||
|
||||
s.emit("room-update", {
|
||||
room,
|
||||
roomId: actualRoom,
|
||||
type: "snapshot",
|
||||
payloads,
|
||||
});
|
||||
}
|
||||
|
||||
log.info(
|
||||
{ room, actualRoom, params },
|
||||
`User joined ${actualRoom}: ${s.id}`,
|
||||
);
|
||||
});
|
||||
s.on("leave-room", (room) => {
|
||||
s.leave(room);
|
||||
log.info({}, `${s.id} left room: ${room}`);
|
||||
// s.on("leave-room", (room) => {
|
||||
// s.leave(room);
|
||||
// log.info({}, `${s.id} left room: ${JSON.stringify(room)}`);
|
||||
// });
|
||||
s.on("leave-room", async ({ room, params }) => {
|
||||
if (!isRoomKey(room)) return;
|
||||
|
||||
const config = roomConfigs[room];
|
||||
|
||||
if (!config) return;
|
||||
|
||||
const actualRoom = config.buildRoom
|
||||
? config.buildRoom(params)
|
||||
: (room as any);
|
||||
|
||||
await s.leave(actualRoom);
|
||||
|
||||
s.emit("room-left", {
|
||||
room,
|
||||
roomId: actualRoom,
|
||||
params,
|
||||
});
|
||||
|
||||
log.info(
|
||||
{ room, actualRoom, params },
|
||||
`${s.id} left room: ${actualRoom}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user