shuttlepro-shared 1.1.70 → 1.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/socket.js +55 -77
- package/package.json +1 -1
package/config/socket.js
CHANGED
|
@@ -1,116 +1,94 @@
|
|
|
1
1
|
const { Server } = require("socket.io");
|
|
2
|
-
const { client: redisClient, connectRedis } = require("./redis");
|
|
3
2
|
const { createClient } = require("redis");
|
|
4
3
|
require("dotenv").config();
|
|
5
4
|
|
|
6
5
|
let io;
|
|
6
|
+
const namespaceSockets = {}; // Store different namespace sockets
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* ✅ Initialize WebSocket Server with Redis Pub/Sub
|
|
10
|
-
* @param {Object} server - HTTP Server instance
|
|
11
|
-
* @param {string|null} namespace - Optional namespace (passed from `index.js`)
|
|
12
|
-
* @param {string} [redisChannel="socket_events"] - Custom Redis Pub/Sub Channel
|
|
13
|
-
*/
|
|
14
8
|
const initializeSocket = async (
|
|
15
9
|
server,
|
|
16
|
-
|
|
10
|
+
namespaceParam = "conversation",
|
|
17
11
|
redisChannel = "socket_events"
|
|
18
12
|
) => {
|
|
19
|
-
|
|
13
|
+
if (!io) {
|
|
14
|
+
io = new Server(server, {
|
|
15
|
+
cors: { origin: "*" },
|
|
16
|
+
});
|
|
17
|
+
}
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
// If namespace is already initialized, return it
|
|
20
|
+
if (namespaceSockets[namespaceParam]) {
|
|
21
|
+
console.log(`⚡ Namespace ${namespaceParam} already initialized`);
|
|
22
|
+
return namespaceSockets[namespaceParam];
|
|
23
|
+
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
25
|
+
// Create new namespace
|
|
26
|
+
const namespace = io.of(`/${namespaceParam}`);
|
|
27
|
+
namespaceSockets[namespaceParam] = namespace;
|
|
28
|
+
console.log(`✅ WebSocket Namespace Initialized: /${namespaceParam}`);
|
|
30
29
|
|
|
31
|
-
// Create Redis
|
|
32
|
-
const pubClient = redisClient;
|
|
30
|
+
// Create Redis subscriber for this namespace
|
|
33
31
|
const subClient = createClient({ url: process.env.REDIS_URL });
|
|
34
32
|
await subClient.connect();
|
|
33
|
+
await subClient.subscribe(redisChannel);
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
subClient.on("message", (channel, message) => {
|
|
36
|
+
console.log(
|
|
37
|
+
`🔔 Redis Event on ${channel} for /${namespaceParam}:`,
|
|
38
|
+
message
|
|
39
|
+
);
|
|
38
40
|
const { workspaceId, event, data } = JSON.parse(message);
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
io.of(namespace).to(workspaceId).emit(event, data);
|
|
42
|
-
} else {
|
|
43
|
-
io.to(workspaceId).emit(event, data);
|
|
44
|
-
}
|
|
42
|
+
namespace.to(workspaceId).emit(event, data);
|
|
45
43
|
});
|
|
46
44
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
handleConnection(socket, namespace)
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* ✅ Handle WebSocket Connection
|
|
56
|
-
* @param {Object} socket - WebSocket client socket
|
|
57
|
-
* @param {string} [namespace] - Optional namespace
|
|
58
|
-
*/
|
|
59
|
-
const handleConnection = async (socket, namespace = null) => {
|
|
60
|
-
const { workspaceId } = socket.handshake.query;
|
|
61
|
-
|
|
62
|
-
if (!workspaceId) {
|
|
63
|
-
console.warn(`❌ Client ${socket.id} rejected due to missing workspaceId`);
|
|
64
|
-
socket.disconnect(true);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
45
|
+
// Handle socket connections per namespace
|
|
46
|
+
namespace.on("connection", (socket) => {
|
|
47
|
+
const { workspaceId } = socket.handshake.query;
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`${workspaceId}:sockets`,
|
|
76
|
-
socket.id,
|
|
77
|
-
JSON.stringify({
|
|
78
|
-
id: socket.id,
|
|
79
|
-
workspaceId,
|
|
80
|
-
namespace,
|
|
81
|
-
connectedAt: new Date().toISOString(),
|
|
82
|
-
})
|
|
83
|
-
);
|
|
49
|
+
if (!workspaceId) {
|
|
50
|
+
console.warn(
|
|
51
|
+
`❌ Client ${socket.id} rejected due to missing workspaceId`
|
|
52
|
+
);
|
|
53
|
+
socket.disconnect(true);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
84
56
|
|
|
85
|
-
// ✅ Handle Disconnection
|
|
86
|
-
socket.on("disconnect", async () => {
|
|
87
57
|
console.log(
|
|
88
|
-
|
|
58
|
+
`✅ Client connected: ${socket.id} (Workspace: ${workspaceId}) in /${namespaceParam}`
|
|
89
59
|
);
|
|
90
|
-
|
|
60
|
+
|
|
61
|
+
socket.join(workspaceId); // Join workspace room
|
|
62
|
+
|
|
63
|
+
socket.on("disconnect", () => {
|
|
64
|
+
console.log(
|
|
65
|
+
`❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId}) in /${namespaceParam}`
|
|
66
|
+
);
|
|
67
|
+
});
|
|
91
68
|
});
|
|
69
|
+
|
|
70
|
+
return namespace;
|
|
92
71
|
};
|
|
93
72
|
|
|
94
|
-
/**
|
|
95
|
-
* ✅ Publish WebSocket Events via Redis
|
|
96
|
-
* @param {string} workspaceId - Target workspace ID
|
|
97
|
-
* @param {string} event - Event name
|
|
98
|
-
* @param {Object} data - Event payload
|
|
99
|
-
* @param {string} [redisChannel="socket_events"] - Custom Redis Pub/Sub Channel
|
|
100
|
-
*/
|
|
101
73
|
const sendEventToServer = async ({
|
|
74
|
+
namespace = "conversation",
|
|
102
75
|
workspaceId,
|
|
103
76
|
event,
|
|
104
77
|
data,
|
|
105
78
|
redisChannel = "socket_events",
|
|
106
79
|
}) => {
|
|
80
|
+
const redisClient = createClient({ url: process.env.REDIS_URL });
|
|
81
|
+
await redisClient.connect();
|
|
82
|
+
|
|
83
|
+
console.log(
|
|
84
|
+
`📤 Sending event '${event}' to namespace '/${namespace}' for workspace '${workspaceId}'`
|
|
85
|
+
);
|
|
107
86
|
await redisClient.publish(
|
|
108
87
|
redisChannel,
|
|
109
88
|
JSON.stringify({ workspaceId, event, data })
|
|
110
89
|
);
|
|
111
|
-
};
|
|
112
90
|
|
|
113
|
-
|
|
114
|
-
initializeSocket,
|
|
115
|
-
sendEventToServer,
|
|
91
|
+
await redisClient.disconnect();
|
|
116
92
|
};
|
|
93
|
+
|
|
94
|
+
module.exports = { initializeSocket, sendEventToServer };
|