From c76886cab128bebf320fc5a825a340088d89ace9 Mon Sep 17 00:00:00 2001 From: sabarinathan155 Date: Fri, 4 Apr 2025 18:28:49 +0530 Subject: [PATCH] assetupdated-event, --- .../services/assets/asset-Controller.ts | 143 --------- src/socket-server/socket/events.ts | 29 +- src/socket-server/socket/socketManager.ts | 299 +++++++++++------- 3 files changed, 192 insertions(+), 279 deletions(-) diff --git a/src/socket-server/services/assets/asset-Controller.ts b/src/socket-server/services/assets/asset-Controller.ts index 78377c4..b186620 100644 --- a/src/socket-server/services/assets/asset-Controller.ts +++ b/src/socket-server/services/assets/asset-Controller.ts @@ -2,148 +2,7 @@ import assetModel from "../../../shared/model/builder/assets/asset-Model.ts"; import actionModel from "../../../shared/model/simulation/actionmodel.ts"; import triggerModel from "../../../shared/model/simulation/triggersmodel.ts"; -// export const setAssetModel = async (data: any) => { -// const { -// modeluuid, -// modelname, -// position, -// rotation, -// eventData, -// modelfileID, -// isLocked, -// isVisible, -// organization, -// } = data; -// console.log("data: ", data); -// // const position=data.position -// // const rotation=data.rotation -// try { -// const findvalue = await assetModel(organization).findOne({ -// modeluuid: modeluuid, -// modelname: modelname, -// isArchive: false, -// }); -// if (findvalue) { -// console.log("findvalue: ", findvalue); -// const updatevalue = await assetModel(organization).findOneAndUpdate( -// { modeluuid: modeluuid, modelname: modelname, isArchive: false }, -// { -// position: position, -// rotation: rotation, -// isVisible: isVisible, -// isLocked: isLocked, -// }, -// { new: true } -// ); -// console.log("updatevalue: ", updatevalue); -// return { -// success: true, -// message: "Model updated successfully", -// data: updatevalue, -// organization: organization, -// }; -// } else { -// let assetData: any = { -// modeluuid, -// modelname, -// position, -// modelfileID, -// rotation, -// isLocked, -// isVisible, -// }; -// if (eventData) { -// let pointRefs: any[] = []; - -// if (Array.isArray(eventData.points)) { -// for (const point of eventData.points) { -// let actionRefs: any[] = []; -// let triggerRefs: any[] = []; - -// if (Array.isArray(point.actions)) { -// for (const action of point.actions) { -// const actionDoc = await actionModel(organization).create({ -// pointsUUID: point.uuid, -// isArchive: false, -// uuid: action.uuid, -// name: action.name, -// type: action.type, -// material: action.material, -// delay: action.delay, -// spawn_Interval: action.spawn_Interval, -// }); -// await actionDoc.save(); -// actionRefs.push(actionDoc._id); -// } -// } - -// if (Array.isArray(point.triggers)) { -// for (const trigger of point.triggers) { -// const triggerDoc = await triggerModel(organization).create({ -// pointsUUID: point.uuid, -// isArchive: false, -// uuid: trigger.uuid, -// name: trigger.name, -// type: trigger.type, -// bufferTime: trigger.bufferTime, -// }); -// await triggerDoc.save(); -// triggerRefs.push(triggerDoc._id); -// } -// } - -// pointRefs.push({ -// uuid: point.uuid, -// position: point.position || [], -// rotation: point.rotation || [], -// actions: actionRefs, -// triggers: triggerRefs, -// connections: point.connections, -// }); -// } -// } - -// assetData.speed = eventData.speed; -// assetData.type = eventData.type; -// assetData.points = pointRefs; -// } - -// const assetDoc = await assetModel(organization).create(assetData); -// await assetDoc.save(); -// // await assetDoc.save(); -// // if(assetDoc.) -// const assetDatas = { -// modeluuid: assetDoc.modeluuid, -// modelname: assetDoc.modelname, -// modelfileID: assetDoc.modelfileID, -// position: assetDoc.position, -// rotation: assetDoc.rotation, -// isLocked: assetDoc.isLocked, -// isVisible: assetDoc.isVisible, -// eventData: { -// points: assetDoc.points, -// type: assetDoc.type, -// speed: assetDoc.speed, -// }, -// }; -// return { -// success: true, -// message: "Model created successfully", -// data: assetDatas, -// organization: organization, -// }; -// } -// } catch (error: any) { -// // console.error("Error creating flooritems:", error); -// return { -// success: false, -// message: error?.message || "Error occurred while ModelAsset", -// error, -// organization: organization, -// }; -// } -// }; export const setAssetModel = async (data: any) => { const { @@ -157,7 +16,6 @@ export const setAssetModel = async (data: any) => { isVisible, organization, } = data; - console.log("data: ", data); try { const findvalue = await assetModel(organization).findOne({ modeluuid: modeluuid, @@ -176,7 +34,6 @@ export const setAssetModel = async (data: any) => { }, { new: true } ); - console.log("updatevalue: ", updatevalue); return { success: true, message: "Model updated successfully", diff --git a/src/socket-server/socket/events.ts b/src/socket-server/socket/events.ts index d5e4153..9973f35 100644 --- a/src/socket-server/socket/events.ts +++ b/src/socket-server/socket/events.ts @@ -44,33 +44,33 @@ export const EVENTS = { deleteLineLayerResponse:"Line:response:delete:layer", //zone setZone:"v2:zone:set", - zoneUpdateRespones:"zone:response:updates", + zoneUpdateResponse:"zone:response:updates", deleteZone:"v2:zone:delete", - ZoneDeleteRespones:"zone:response:delete", + ZoneDeleteResponse:"zone:response:delete", //visualization addPanel:"v2:viz-panel:add", - panelUpdateRespones:"viz-panel:response:updates", + panelUpdateResponse:"viz-panel:response:updates", deletePanel:"v2:viz-panel:delete", - PanelDeleteRespones:"viz-panel:response:delete", + PanelDeleteResponse:"viz-panel:response:delete", //widget addWidget:"v2:viz-widget:add", - widgetUpdateRespones:"viz-widget:response:updates", + widgetUpdateResponse:"viz-widget:response:updates", deleteWidget:"v2:viz-widget:delete", - widgetDeleteRespones:"viz-widget:response:delete", + widgetDeleteResponse:"viz-widget:response:delete", //float addFloat: "v2:viz-float:add", - floatUpdateRespones: "viz-float:response:updates", + floatUpdateResponse: "viz-float:response:updates", deleteFloat: "v2:viz-float:delete", - floatDeleteRespones: "viz-float:response:delete", + floatDeleteResponse: "viz-float:response:delete", duplicatefloat:"v2:viz-float:addDuplicate", - duplicatefloatUpdateRespones:"viz-float:response:addDuplicate", + duplicatefloatUpdateResponse:"viz-float:response:addDuplicate", //template addTemplate:"v2:viz-template:add", - templateUpdateRespones:"viz-template:response:add", + templateUpdateResponse:"viz-template:response:add", addTemplateZone:"v2:viz-template:addToZone", addTemplateZoneResponse:"viz-template:response:addTemplateZone", deleteTemplate:"v2:viz-template:deleteTemplate", @@ -79,13 +79,16 @@ export const EVENTS = { //model-asset setAssetModel: "v2:model-asset:add", - assetUpdateRespones: "model-asset:response:updates", + assetUpdateResponse: "model-asset:response:updates", deleteAssetModel:"v2:model-asset:delete", - assetDeleteRespones: "model-asset:response:updates", + assetDeleteResponse: "model-asset:response:updates", + assetEventData:"v2:model-asset:updateEventData", + assetEventDataResponse: "model-asset:response:updateEventData", + //3Dwidget add3DWidget:"v2:viz-3D-widget:add", - widget3DUpdateRespones:"viz-widget3D:response:updates", + widget3DUpdateResponse:"viz-widget3D:response:updates", } \ No newline at end of file diff --git a/src/socket-server/socket/socketManager.ts b/src/socket-server/socket/socketManager.ts index 03e99dd..5fb3a22 100644 --- a/src/socket-server/socket/socketManager.ts +++ b/src/socket-server/socket/socketManager.ts @@ -11,7 +11,7 @@ import { addPanel, panelDelete } from '../services/visualization/panel-Services. import { addWidget, Widgetdelete } from '../services/visualization/widget-Services.ts'; import { addfloat, deletefloat, duplicatefloat } from '../services/visualization/floatWidget-Service.ts'; import { addTemplate, addTemplateZone, TemplateZoneDelete } from '../services/visualization/templateServices.ts'; -import { deleteAssetModel, setAssetModel } from '../services/assets/asset-Controller.ts'; +import { deleteAssetModel, replaceEventDatas, setAssetModel } from '../services/assets/asset-Controller.ts'; import { add3Dwidget } from '../services/visualization/3dWidget-Service.ts'; @@ -25,6 +25,7 @@ const cameraHandleEvent = async (event: string, socket: Socket, data: any, names let result; switch (event) { + case EVENTS.setCamera: { result = await createCamera(data); @@ -52,7 +53,7 @@ const cameraHandleEvent = async (event: string, socket: Socket, data: any, names // const result = await Widgetdelete(data) // if (result) { // // console.log('result?.success: ', result.organization); - // const responseEvent = EVENTS.widgetDeleteRespones + // const responseEvent = EVENTS.widgetDeleteResponse // // console.log('responseEvent: ', responseEvent); // const organization = result?.organization // // console.log('organization: ', organization); @@ -113,7 +114,7 @@ const EnvironmentHandleEvent = async (event: string, socket: Socket, data: any, // const result = await Widgetdelete(data) // if (result) { // // console.log('result?.success: ', result.organization); - // const responseEvent = EVENTS.widgetDeleteRespones + // const responseEvent = EVENTS.widgetDeleteResponse // // console.log('responseEvent: ', responseEvent); // const organization = result?.organization // // console.log('organization: ', organization); @@ -449,7 +450,7 @@ const zoneHandleEvent = async (event: string, socket: Socket, data: any, io: any result = await setZone(data); if (result) { - const responseEvent = EVENTS.zoneUpdateRespones + const responseEvent = EVENTS.zoneUpdateResponse const organization = result?.organization // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); @@ -472,7 +473,7 @@ const zoneHandleEvent = async (event: string, socket: Socket, data: any, io: any const result = await deleteZone(data) if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.ZoneDeleteRespones + const responseEvent = EVENTS.ZoneDeleteResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -507,7 +508,7 @@ const panelHandleEvent = async (event: string, socket: Socket, data: any, namesp case EVENTS.addPanel: { result = await addPanel(data); if (result) { - const responseEvent = EVENTS.panelUpdateRespones + const responseEvent = EVENTS.panelUpdateResponse const organization = result?.organization // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); @@ -528,7 +529,7 @@ const panelHandleEvent = async (event: string, socket: Socket, data: any, namesp const result = await panelDelete(data) if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.PanelDeleteRespones + const responseEvent = EVENTS.PanelDeleteResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -569,7 +570,7 @@ const widgetHandleEvent = async (event: string, socket: Socket, data: any, names if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.widgetUpdateRespones + const responseEvent = EVENTS.widgetUpdateResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -591,7 +592,7 @@ const widgetHandleEvent = async (event: string, socket: Socket, data: any, names const result = await Widgetdelete(data) if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.widgetDeleteRespones + const responseEvent = EVENTS.widgetDeleteResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization @@ -631,7 +632,7 @@ const floatHandleEvent = async (event: string, socket: Socket, data: any, namesp if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.floatUpdateRespones + const responseEvent = EVENTS.floatUpdateResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -653,7 +654,7 @@ const floatHandleEvent = async (event: string, socket: Socket, data: any, namesp const result = await deletefloat(data) if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.floatDeleteRespones + const responseEvent = EVENTS.floatDeleteResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -690,7 +691,7 @@ const templateHandleEvent = async (event: string, socket: Socket, data: any, nam result = await addTemplate(data); if (result) { - const responseEvent = EVENTS.templateUpdateRespones + const responseEvent = EVENTS.templateUpdateResponse const organization = result?.organization // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); @@ -757,7 +758,7 @@ const templateHandleEvent = async (event: string, socket: Socket, data: any, nam const result = await duplicatefloat(data) if (result) { // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.duplicatefloatUpdateRespones + const responseEvent = EVENTS.duplicatefloatUpdateResponse // console.log('responseEvent: ', responseEvent); const organization = result?.organization if (organization) { @@ -794,7 +795,7 @@ const Widget3DHandleEvent = async (event: string, socket: Socket, data: any, nam result = await add3Dwidget(data); if (result) { - const responseEvent = EVENTS.widget3DUpdateRespones + const responseEvent = EVENTS.widget3DUpdateResponse const organization = result?.organization // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); @@ -818,7 +819,7 @@ const Widget3DHandleEvent = async (event: string, socket: Socket, data: any, nam // const result = await Widgetdelete(data) // if (result) { // // console.log('result?.success: ', result.organization); - // const responseEvent = EVENTS.widgetDeleteRespones + // const responseEvent = EVENTS.widgetDeleteResponse // // console.log('responseEvent: ', responseEvent); // const organization = result?.organization // // console.log('organization: ', organization); @@ -855,57 +856,126 @@ const modelAssetHandleEvent = async (event: string, socket: Socket, data: any, n let result; switch (event) { - case EVENTS.setAssetModel: { + case EVENTS.setAssetModel: result = await setAssetModel(data); + if (result) emitEventResponse(socket, result.organization, EVENTS.assetUpdateResponse, result); + break; + case EVENTS.deleteAssetModel: + result = await deleteAssetModel(data); + if (result) emitEventResponse(socket, result.organization, EVENTS.assetDeleteResponse, result); + break; + case EVENTS.assetEventData: + result = await replaceEventDatas(data); + if (result) emitEventResponse(socket, result.organization, EVENTS.assetEventDataResponse, result); + break; + // case EVENTS.setAssetModel: { + // result = await setAssetModel(data); - if (result) { - const responseEvent = EVENTS.assetUpdateRespones - const organization = result?.organization - // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); - // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); - if (organization) { - socket.to(organization).emit(responseEvent, { - success: result.success, - message: result.message, - data: result.data, - error: result.error || null, - socketId: socket.id, - organization, - }); - } else { - console.warn(`Organization missing in response for event: ${event}`); - } - } - break - } - case EVENTS.deleteAssetModel: { - const result = await deleteAssetModel(data) - if (result) { - // console.log('result?.success: ', result.organization); - const responseEvent = EVENTS.assetDeleteRespones - // console.log('responseEvent: ', responseEvent); - const organization = result?.organization - if (organization) { - socket.to(organization).emit(responseEvent, { - success: result.success, - message: result.message, - data: result.data, - error: result.error || null, - socketId: socket.id, - organization, - }); - } else { - console.warn(`Organization missing in response for event: ${event}`); - } - } - break - } - + // if (result) { + // const responseEvent = EVENTS.assetUpdateResponse + // const organization = result?.organization + // // const emitTarget = notifySender ? socket.in(organization) : socket.to(organization); + // // console.log(`👀 Active sockets in room:`, namespace.adapter.rooms.get(organization)); + // if (organization) { + // socket.to(organization).emit(responseEvent, { + // success: result.success, + // message: result.message, + // data: result.data, + // error: result.error || null, + // socketId: socket.id, + // organization, + // }); + // } else { + // console.warn(`Organization missing in response for event: ${event}`); + // } + // } + // break + // } + // case EVENTS.deleteAssetModel: { + // const result = await deleteAssetModel(data) + // if (result) { + // // console.log('result?.success: ', result.organization); + // const responseEvent = EVENTS.assetDeleteResponse + // // console.log('responseEvent: ', responseEvent); + // const organization = result?.organization + // if (organization) { + // socket.to(organization).emit(responseEvent, { + // success: result.success, + // message: result.message, + // data: result.data, + // error: result.error || null, + // socketId: socket.id, + // organization, + // }); + // } else { + // console.warn(`Organization missing in response for event: ${event}`); + // } + // } + // break + // } + // case EVENTS.assetEventData: { + // const result = await replaceEventDatas(data) + // if (result) { + // // console.log('result?.success: ', result.organization); + // const responseEvent = EVENTS.assetEventDataResponse + // // console.log('responseEvent: ', responseEvent); + // const organization = result?.organization + // if (organization) { + // socket.to(organization).emit(responseEvent, { + // success: result.success, + // message: result.message, + // data: result.data, + // error: result.error || null, + // socketId: socket.id, + // organization, + // }); + // } else { + // console.warn(`Organization missing in response for event: ${event}`); + // } + // } + // break + // } default: return; } } +const simulationHandleEvent = async (event: string, socket: Socket, data: any,) => { + // console.log('data: ', data); + if (!data?.organization) { + console.warn(`Missing organization for event: ${event}`); + return; + } + let result; +try { + switch (event) { + case EVENTS.setAssetModel: + result = await addTemplate(data); + if (result) emitEventResponse(socket, result.organization, EVENTS.zoneUpdateResponse, result); + break; + default: + console.warn(`❌ Unknown event received: ${event}`); + } +} catch (error) { + console.error(`❌ Error handling event ${event}:`, error); + +} + +} +const emitEventResponse = (socket: Socket, organization: string, event: string, result: any) => { + if (organization) { + socket.to(organization).emit(event, { + success: result.success, + message: result.message, + data: result.data, + error: result.error || null, + socketId: socket.id, + organization, + }); + } else { + console.warn(`Organization missing in response for event: ${event}`); + } +}; export const initSocketServer = (httpServer: any) => { const io = new Server(httpServer, { @@ -917,73 +987,46 @@ export const initSocketServer = (httpServer: any) => { // Listen for new connections - io.on(EVENTS.connection, (socket: Socket) => { - // console.log(`New client connected: ${socket.id}`); - // console.log(socket.handshake.auth); - userStatus(EVENTS.connection, socket, socket.handshake.auth, io); + // io.on(EVENTS.connection, (socket: Socket) => { + // // console.log(`New client connected: ${socket.id}`); + // // console.log(socket.handshake.auth); + // userStatus(EVENTS.connection, socket, socket.handshake.auth, io); + // // console.log('socket.handshake.auth: ', socket.handshake.auth); - // Handle all incoming events with the handleEvent function - socket.onAny((event: string, data: any,) => { - cameraHandleEvent(event, socket, data, io); - EnvironmentHandleEvent(event, socket, data, io); - floorItemsHandleEvent(event, socket, data, io); - wallItemsHandleEvent(event, socket, data, io); - lineHandleEvent(event, socket, data, io); - zoneHandleEvent(event, socket, data, io); + // // Handle all incoming events with the handleEvent function + // socket.onAny((event: string, data: any,) => { + // cameraHandleEvent(event, socket, data, io); + // EnvironmentHandleEvent(event, socket, data, io); + // floorItemsHandleEvent(event, socket, data, io); + // wallItemsHandleEvent(event, socket, data, io); + // lineHandleEvent(event, socket, data, io); + // zoneHandleEvent(event, socket, data, io); - }); - socket.on(EVENTS.disconnect, (reason: string) => { - // console.log(`Client disconnected: ${socket.id}, Reason: ${reason}`); - // console.log(socket.handshake.auth); - userStatus(EVENTS.disconnect, socket, socket.handshake.auth, io); - // Perform cleanup or other necessary actions - }); - }); + // }); + // socket.on(EVENTS.disconnect, (reason: string) => { + // // console.log(`Client disconnected: ${socket.id}, Reason: ${reason}`); + // // console.log(socket.handshake.auth); + // userStatus(EVENTS.disconnect, socket, socket.handshake.auth, io); + // // Perform cleanup or other necessary actions + // }); + // }); // 🔹 Create different namespaces const namespaces = { - camera: io.of("/camera"), - environment: io.of("/environment"), - floorItems: io.of("/floorItems"), - wallItems: io.of("/wallItems"), - line: io.of("/line"), - zone: io.of("/zone"), + // camera: io.of("/camera"), + // environment: io.of("/environment"), + // floorItems: io.of("/floorItems"), + // wallItems: io.of("/wallItems"), + // line: io.of("/line"), + // zone: io.of("/zone"), Builder: io.of('/Builder'), visualization: io.of('/Visualization'), // widget:io.of('/widget') }; - // 🔹 Function to handle connections in a namespace - // const handleNamespace = (namespaceName: string, namespace: any, ...eventHandlers: Function[]) => { - // namespace.on("connection", (socket: Socket) => { - // console.log(`✅ Client connected to ${namespaceName}: ${socket.id}`); + + // const onlineUsers = new Map>(); + const onlineUsers: { [organization: string]: Set } = {}; - // // Extract organization from query parameters - // // const organization = socket.handshake.query.organization as string; - // const organization = socket.handshake.auth.organization as string; - // console.log(`🔍 Received organization: ${organization}`); - - // if (organization) { - // socket.join(organization); - // // console.log(`🔹 Socket ${socket.id} joined room: ${organization}`); - - // // Debug: Check rooms - // // console.log(`🛠️ Current rooms for ${socket.id}:`, socket.rooms); - // } else { - // console.warn(`⚠️ Warning: Socket ${socket.id} did not provide an organization`); - // } - - // socket.onAny((event: string, data: any) => { - // // console.log(`📩 Event received: ${event}, Data: ${JSON.stringify(data)}`); - // eventHandlers.forEach(handler => handler(event, socket, data, namespace)); - // // eventHandler(event, socket, data, namespace); // Pass `namespace` instead of `io` - // }); - - // socket.on("disconnect", (reason: string) => { - // console.log(`❌ Client disconnected from ${namespaceName}: ${socket.id}, Reason: ${reason}`); - // }); - // }); - // }; - const onlineUsers = new Map>(); const handleNamespace = (namespaceName: string, namespace: any, ...eventHandlers: Function[]) => { @@ -991,18 +1034,26 @@ export const initSocketServer = (httpServer: any) => { // console.log(`✅ Client connected to ${namespaceName}: ${socket.id}`); // Extract organization from query parameters - // const organization = socket.handshake.query.organization as string; - const {organization,email} = socket.handshake.auth + const organization = socket.handshake.query.organization as string; + const email = socket.handshake.query.email as string; + // const {organization,email} = socket.handshake.auth // console.log(`🔍 Received organization: ${organization}`); if (organization) { socket.join(organization); // console.log(`🔹 Socket ${socket.id} joined room: ${organization}`); - } else { - // console.warn(`⚠️ Warning: Socket ${socket.id} did not provide an organization`); } - // addUserToOnlineList(organization, socket.id, onlineUsers, socket, namespaceName); // Handle all events + if (organization && email) { + if (!onlineUsers[organization]) { + onlineUsers[organization] = new Set(); + } + onlineUsers[organization].add(socket.id); + console.log('onlineUsers: ', onlineUsers); + + console.log(`✅ User ${email} joined ${organization}. Active users:`, onlineUsers[organization]); + } + userStatus(EVENTS.connection, socket, socket.handshake.auth, socket); socket.onAny((event: string, data: any) => { @@ -1010,9 +1061,11 @@ export const initSocketServer = (httpServer: any) => { }); // Handle disconnection - socket.on("disconnect", (reason: string) => { + socket.on("disconnect", () => { + onlineUsers[organization]?.delete(socket.id); + if (onlineUsers[organization]?.size === 0) delete onlineUsers[organization]; userStatus(EVENTS.disconnect, socket, socket.handshake.auth, socket); - + // console.log(`❌ User ${email} disconnected. Remaining:`, onlineUsers[organization]); // console.log(`❌ Client disconnected from ${namespaceName}: ${socket.id}, Reason: ${reason}`); });