shuttlepro-shared 1.1.74 → 1.1.76
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 +98 -20
- package/models/Profile.js +8 -1
- package/package.json +1 -1
package/config/socket.js
CHANGED
|
@@ -1,48 +1,88 @@
|
|
|
1
1
|
const { Server } = require("socket.io");
|
|
2
|
-
const { publisher, subscriber, connectRedis } = require("./redis");
|
|
2
|
+
const { publisher, subscriber, connectRedis } = require("./redis");
|
|
3
3
|
require("dotenv").config();
|
|
4
4
|
|
|
5
5
|
let io;
|
|
6
6
|
const namespaceSockets = {}; // Store different namespace sockets
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Initialize Socket.IO server with namespaces
|
|
10
|
+
* @param {http.Server} server - HTTP server instance
|
|
11
|
+
* @param {string} namespaceParam - Socket namespace name (default: "conversation")
|
|
12
|
+
* @param {string} redisChannel - Redis channel for this namespace (default: "socket_events")
|
|
13
|
+
* @returns {SocketIO.Namespace} - The initialized namespace
|
|
14
|
+
*/
|
|
8
15
|
const initializeSocket = async (
|
|
9
16
|
server,
|
|
10
17
|
namespaceParam = "conversation",
|
|
11
18
|
redisChannel = "socket_events"
|
|
12
19
|
) => {
|
|
20
|
+
// Initialize Socket.IO server if not already done
|
|
13
21
|
if (!io) {
|
|
14
22
|
io = new Server(server, {
|
|
15
|
-
cors: {
|
|
23
|
+
cors: {
|
|
24
|
+
origin: "*",
|
|
25
|
+
methods: ["GET", "POST"],
|
|
26
|
+
},
|
|
16
27
|
});
|
|
28
|
+
console.log("✅ Socket.IO server initialized");
|
|
17
29
|
}
|
|
18
30
|
|
|
19
31
|
// Return existing namespace if already initialized
|
|
20
32
|
if (namespaceSockets[namespaceParam]) {
|
|
33
|
+
console.log(`📢 Using existing namespace: /${namespaceParam}`);
|
|
21
34
|
return namespaceSockets[namespaceParam];
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
// Create and store namespace
|
|
37
|
+
// Create and store new namespace
|
|
25
38
|
const namespace = io.of(`/${namespaceParam}`);
|
|
26
39
|
namespaceSockets[namespaceParam] = namespace;
|
|
40
|
+
console.log(`🚀 Created new namespace: /${namespaceParam}`);
|
|
27
41
|
|
|
28
42
|
// Ensure Redis is connected
|
|
29
43
|
await connectRedis();
|
|
30
44
|
|
|
45
|
+
// Create a unique Redis channel for this namespace
|
|
46
|
+
const nsRedisChannel = `${redisChannel}_${namespaceParam}`;
|
|
47
|
+
|
|
31
48
|
// Subscribe to Redis events for this namespace
|
|
32
|
-
await subscriber.subscribe(
|
|
49
|
+
await subscriber.subscribe(nsRedisChannel, (messageStr) => {
|
|
33
50
|
try {
|
|
34
|
-
const
|
|
35
|
-
|
|
51
|
+
const message = JSON.parse(messageStr);
|
|
52
|
+
const { workspaceId, event, data } = message;
|
|
53
|
+
|
|
54
|
+
console.log(`📥 Redis message received on ${nsRedisChannel}:`, {
|
|
55
|
+
workspaceId,
|
|
56
|
+
event,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Emit to specific workspace room in this namespace
|
|
60
|
+
if (workspaceId) {
|
|
61
|
+
namespace.to(workspaceId).emit(event, data);
|
|
62
|
+
console.log(
|
|
63
|
+
`📢 Event ${event} emitted to workspace ${workspaceId} in /${namespaceParam}`
|
|
64
|
+
);
|
|
65
|
+
} else {
|
|
66
|
+
// Broadcast to all clients in this namespace if no workspaceId specified
|
|
67
|
+
namespace.emit(event, data);
|
|
68
|
+
console.log(
|
|
69
|
+
`📢 Event ${event} broadcasted to all clients in /${namespaceParam}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
36
72
|
} catch (err) {
|
|
37
|
-
console.error(
|
|
73
|
+
console.error(
|
|
74
|
+
`❌ Error handling Redis message on ${nsRedisChannel}:`,
|
|
75
|
+
err
|
|
76
|
+
);
|
|
38
77
|
}
|
|
39
78
|
});
|
|
40
79
|
|
|
41
|
-
// Handle new socket connections
|
|
80
|
+
// Handle new socket connections to this namespace
|
|
42
81
|
namespace.on("connection", (socket) => {
|
|
43
82
|
const { workspaceId } = socket.handshake.query;
|
|
44
83
|
|
|
45
84
|
if (!workspaceId) {
|
|
85
|
+
console.warn(`⚠️ Connection rejected: No workspaceId provided`);
|
|
46
86
|
socket.disconnect(true);
|
|
47
87
|
return;
|
|
48
88
|
}
|
|
@@ -51,43 +91,81 @@ const initializeSocket = async (
|
|
|
51
91
|
`✅ Client connected: ${socket.id} (Workspace: ${workspaceId}) in /${namespaceParam}`
|
|
52
92
|
);
|
|
53
93
|
|
|
54
|
-
|
|
94
|
+
// Join workspace room
|
|
95
|
+
socket.join(workspaceId);
|
|
96
|
+
|
|
97
|
+
// Send connection confirmation to client
|
|
98
|
+
socket.emit("connected", {
|
|
99
|
+
status: "connected",
|
|
100
|
+
socketId: socket.id,
|
|
101
|
+
namespace: namespaceParam,
|
|
102
|
+
workspaceId,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Handle custom events from clients
|
|
106
|
+
socket.on("client_event", (data) => {
|
|
107
|
+
console.log(`📥 Client event from ${socket.id}:`, data);
|
|
108
|
+
// You can process client events here
|
|
109
|
+
});
|
|
55
110
|
|
|
56
|
-
|
|
111
|
+
// Handle disconnect
|
|
112
|
+
socket.on("disconnect", (reason) => {
|
|
57
113
|
console.log(
|
|
58
|
-
`❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId})`
|
|
114
|
+
`❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId}, Reason: ${reason})`
|
|
59
115
|
);
|
|
60
116
|
socket.leave(workspaceId);
|
|
61
117
|
});
|
|
118
|
+
|
|
119
|
+
// Handle errors
|
|
120
|
+
socket.on("error", (error) => {
|
|
121
|
+
console.error(`❌ Socket error for ${socket.id}:`, error);
|
|
122
|
+
});
|
|
62
123
|
});
|
|
63
124
|
|
|
125
|
+
console.log(
|
|
126
|
+
`✅ Namespace /${namespaceParam} initialized and listening on Redis channel: ${nsRedisChannel}`
|
|
127
|
+
);
|
|
64
128
|
return namespace;
|
|
65
129
|
};
|
|
66
130
|
|
|
67
131
|
/**
|
|
68
|
-
*
|
|
69
|
-
* @param {object} params - Event
|
|
132
|
+
* Send event to clients via Redis pub/sub
|
|
133
|
+
* @param {object} params - Event parameters
|
|
70
134
|
* @param {string} params.workspaceId - Target workspace ID
|
|
71
135
|
* @param {string} params.event - Event name
|
|
72
|
-
* @param {any} params.data - Event data
|
|
73
|
-
* @param {string} [params.
|
|
136
|
+
* @param {any} params.data - Event data payload
|
|
137
|
+
* @param {string} [params.namespace="conversation"] - Target namespace
|
|
138
|
+
* @param {string} [params.redisChannel="socket_events"] - Base Redis channel
|
|
139
|
+
* @returns {Promise<void>}
|
|
74
140
|
*/
|
|
75
141
|
const sendEventToServer = async ({
|
|
76
142
|
workspaceId,
|
|
77
143
|
event,
|
|
78
144
|
data,
|
|
145
|
+
namespace = "conversation",
|
|
79
146
|
redisChannel = "socket_events",
|
|
80
147
|
}) => {
|
|
81
148
|
try {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
149
|
+
// Create namespace-specific Redis channel
|
|
150
|
+
const nsRedisChannel = `${redisChannel}_${namespace}`;
|
|
151
|
+
|
|
152
|
+
// Ensure Redis is connected
|
|
153
|
+
await connectRedis();
|
|
154
|
+
|
|
155
|
+
// Create message payload
|
|
156
|
+
const message = JSON.stringify({ workspaceId, event, data });
|
|
157
|
+
|
|
158
|
+
// Publish to Redis
|
|
159
|
+
await publisher.publish(nsRedisChannel, message);
|
|
160
|
+
|
|
86
161
|
console.log(
|
|
87
|
-
`📢 Event published to Redis: ${event} (Workspace: ${workspaceId})`
|
|
162
|
+
`📢 Event published to Redis channel ${nsRedisChannel}: ${event} (Workspace: ${workspaceId})`
|
|
88
163
|
);
|
|
164
|
+
|
|
165
|
+
return true;
|
|
89
166
|
} catch (err) {
|
|
90
167
|
console.error("❌ Error publishing to Redis:", err);
|
|
168
|
+
throw err;
|
|
91
169
|
}
|
|
92
170
|
};
|
|
93
171
|
|
package/models/Profile.js
CHANGED
|
@@ -89,7 +89,14 @@ const createProfile = async (obj) => {
|
|
|
89
89
|
};
|
|
90
90
|
const createUpdateProfileModified = async (filter, obj) => {
|
|
91
91
|
try {
|
|
92
|
-
let profile = await Profile.findOneAndUpdate(
|
|
92
|
+
let profile = await Profile.findOneAndUpdate(
|
|
93
|
+
filter,
|
|
94
|
+
{ ...obj, ...filter },
|
|
95
|
+
{
|
|
96
|
+
new: true,
|
|
97
|
+
upsert: true,
|
|
98
|
+
}
|
|
99
|
+
);
|
|
93
100
|
await addOrUpdateProfilesInRedis(profile);
|
|
94
101
|
return profile;
|
|
95
102
|
} catch (err) {
|