@nsshunt/stssocketioutils 2.0.33 → 2.0.35

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/dist/node.mjs CHANGED
@@ -1,449 +1,381 @@
1
+ import { t as require_tiny_emitter } from "./tiny-emitter-GH7XS7wi.mjs";
1
2
  import { Sleep } from "@nsshunt/stsutils";
2
3
  import { Server } from "socket.io";
3
4
  import { Redis } from "ioredis";
4
- import { createAdapter as createAdapter$1 } from "@socket.io/cluster-adapter";
5
- import { createAdapter } from "@socket.io/redis-streams-adapter";
6
- import { t as tinyEmitterExports } from "./index-snr1zbog.mjs";
7
- class SocketIoServer extends tinyEmitterExports.TinyEmitter {
8
- namespace;
9
- socketionamespace;
10
- //protected socketionamespace?: Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents>
11
- logger;
12
- io;
13
- //#redisClient: RedisClientType | Redis | null = null;
14
- redisClient;
15
- listenPort;
16
- socketIoCustomPath;
17
- ioRedisMessageProcessorUrl;
18
- serverClusterMode;
19
- rooms;
20
- serverName;
21
- draining = false;
22
- attached = false;
23
- constructor(serverName) {
24
- super();
25
- this.serverName = serverName;
26
- }
27
- get logPrefix() {
28
- if (this.namespace) {
29
- return `SocketIoServer[${this.serverName}:${this.namespace}]: `;
30
- } else {
31
- return `SocketIoServer[${this.serverName}:<No Namespace>]: `;
32
- }
33
- }
34
- LogErrorMessage(message) {
35
- if (this.logger) {
36
- this.logger.error(`${this.logPrefix}${message}`);
37
- }
38
- }
39
- LogDebugMessage(message) {
40
- if (this.logger) {
41
- this.logger.debug(`${this.logPrefix}${message}`);
42
- }
43
- }
44
- LogInfoMessage(message) {
45
- if (this.logger) {
46
- this.logger.info(`${this.logPrefix}${message}`);
47
- }
48
- }
49
- LogWarnMessage(message) {
50
- if (this.logger) {
51
- this.logger.warn(`${this.logPrefix}${message}`);
52
- }
53
- }
54
- LogSillyMessage(message) {
55
- if (this.logger) {
56
- this.logger.silly(`${this.logPrefix}${message}`);
57
- }
58
- }
59
- LogVerboseMessage(message) {
60
- if (this.logger) {
61
- this.logger.verbose(`${this.logPrefix}${message}`);
62
- }
63
- }
64
- LogHttpMessage(message) {
65
- if (this.logger) {
66
- this.logger.http(`${this.logPrefix}${message}`);
67
- }
68
- }
69
- // https://socket.io/docs/v4/middlewares/
70
- // https://socket.io/docs/v4/server-socket-instance/#sockethandshake
71
- // https://socket.io/docs/v4/server-socket-instance/#socket-middlewares
72
- // Use this middleward to check every incomming connection
73
- SetupConnectionMiddleware = () => {
74
- };
75
- // Use this middleware to check every packet being received
76
- SetupMessageMiddleware = (socket) => {
77
- };
78
- /*
79
- protected GetConfig = (socketIoServeroptions: ISocketIoServerOpitons): Partial<ServerOptions> => {
80
- //this.#redisClient = createClient({url: this.#options.ioRedisMessageProcessorUrl});
81
- //await this.#redisClient.connect();
82
- this.LogDebugMessage(`GetConfig() transports: [ [websocket] ]`);
83
- const options: Partial<ServerOptions> = {
84
- transports: [ "websocket" ], // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
85
- }
86
-
87
- if (socketIoServeroptions.ioRedisMessageProcessorUrl && socketIoServeroptions.ioRedisMessageProcessorUrl !== '') {
88
- this.redisClient = new Redis(socketIoServeroptions.ioRedisMessageProcessorUrl);
89
- this.LogDebugMessage(`GetConfig() createAdapter(redis): redis url: [${socketIoServeroptions.ioRedisMessageProcessorUrl}]`);
90
- options.adapter = createAdapter(this.redisClient) as any;
91
- } else if (socketIoServeroptions.serverClusterMode && socketIoServeroptions.serverClusterMode === true) {
92
- this.LogDebugMessage(`GetConfig() createAdapter(cluster)`);
93
- options.adapter = clusterCreateAdapter() as any;
94
- }
95
-
96
- if (socketIoServeroptions.wssCustomPath && socketIoServeroptions.wssCustomPath.localeCompare('') !== 0) {
97
- this.LogDebugMessage(`GetConfig() wssCustomPath: [${socketIoServeroptions.wssCustomPath}]`);
98
- options.path = socketIoServeroptions.wssCustomPath;
99
- }
100
-
101
- return options;
102
- }
103
- */
104
- SetEngineEvents = () => {
105
- if (this.io) {
106
- this.io.engine.on("connection_error", (err) => {
107
- this.LogWarnMessage(`SetEngineEvents(): connection_error`);
108
- this.LogWarnMessage(err.req);
109
- this.LogWarnMessage(err.code);
110
- this.LogWarnMessage(err.message);
111
- this.LogWarnMessage(err.context);
112
- });
113
- }
114
- };
115
- WithLogger = (logger) => {
116
- this.logger = logger;
117
- return this;
118
- };
119
- WithListenPort = (listenPort) => {
120
- this.listenPort = listenPort;
121
- return this;
122
- };
123
- WithSocketIoCustomPath = (socketIoCustomPath) => {
124
- this.socketIoCustomPath = socketIoCustomPath;
125
- return this;
126
- };
127
- WithIoRedisMessageProcessorUrl = (ioRedisMessageProcessorUrl) => {
128
- this.ioRedisMessageProcessorUrl = ioRedisMessageProcessorUrl;
129
- return this;
130
- };
131
- WithClusterMode = (serverClusterMode) => {
132
- this.serverClusterMode = serverClusterMode;
133
- return this;
134
- };
135
- WithRooms = (rooms) => {
136
- this.rooms = rooms;
137
- return this;
138
- };
139
- WithNamespace = (namespace) => {
140
- this.namespace = namespace;
141
- return this;
142
- };
143
- AttachSocketIoServer = async (server) => {
144
- if (!this.io) {
145
- this.LogInfoMessage(`AttachServer(): io = server`);
146
- this.io = server;
147
- this.LogInfoMessage(`AttachServer(): attached = true`);
148
- this.attached = true;
149
- this.LogInfoMessage(`AttachServer(): SetupNamespace()`);
150
- this.SetupNamespace();
151
- } else {
152
- const errorMessage = this.attached === true ? `AttachServer(): Server already exists (from AttachServer())` : `AttachServer(): Server already exists (from StartServer())`;
153
- this.LogErrorMessage(errorMessage);
154
- throw new Error(errorMessage);
155
- }
156
- return this;
157
- };
158
- StartSocketIoServer = async () => {
159
- if (!this.namespace) {
160
- const errorMessage = `StartServer(): Error: [namespace not specified]`;
161
- this.LogErrorMessage(errorMessage);
162
- throw new Error(errorMessage);
163
- }
164
- if (!this.io) {
165
- if (!this.listenPort) {
166
- const errorMessage = `StartServer(): Error: [listenPort not specified]`;
167
- this.LogErrorMessage(errorMessage);
168
- throw new Error(errorMessage);
169
- }
170
- this.LogDebugMessage(`StartServer(): draining = false`);
171
- this.draining = false;
172
- this.LogDebugMessage(`StartServer(): transports: [ [websocket] ]`);
173
- const options = {
174
- transports: ["websocket"]
175
- // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
176
- };
177
- if (this.ioRedisMessageProcessorUrl && this.ioRedisMessageProcessorUrl !== "") {
178
- this.redisClient = new Redis(this.ioRedisMessageProcessorUrl);
179
- this.LogDebugMessage(`StartServer(): createAdapter(redis): redis url: [${this.ioRedisMessageProcessorUrl}]`);
180
- options.adapter = createAdapter(this.redisClient);
181
- } else if (this.serverClusterMode && this.serverClusterMode === true) {
182
- this.LogDebugMessage(`StartServer(): createAdapter(cluster)`);
183
- options.adapter = createAdapter$1();
184
- }
185
- if (this.socketIoCustomPath && this.socketIoCustomPath.localeCompare("") !== 0) {
186
- this.LogDebugMessage(`StartServer(): socketIoCustomPath: [${this.socketIoCustomPath}]`);
187
- options.path = this.socketIoCustomPath;
188
- }
189
- this.LogDebugMessage(`StartServer(): new Server(): listenPort: [${this.listenPort}]`);
190
- this.io = new Server(this.listenPort, options);
191
- this.LogDebugMessage(`StartServer(): SetEngineEvents()`);
192
- this.SetEngineEvents();
193
- this.LogDebugMessage(`StartServer(): Sleeping ...`);
194
- await Sleep(500);
195
- this.LogDebugMessage(`StartServer(): Done Sleeping`);
196
- this.LogInfoMessage(`AttachServer(): attached = false`);
197
- this.attached = false;
198
- this.LogInfoMessage(`StartServer(): SetupNamespace()`);
199
- this.SetupNamespace();
200
- } else {
201
- const errorMessage = this.attached === true ? `StartServer(): Server already exists (from AttachServer())` : `StartServer(): Server already exists (from StartServer())`;
202
- this.LogErrorMessage(errorMessage);
203
- throw new Error(errorMessage);
204
- }
205
- return this;
206
- };
207
- DetachSockerIoServer = async () => {
208
- if (this.io) {
209
- if (this.attached === true) {
210
- this.LogInfoMessage(`DetachServer(): StopNamespace()`);
211
- await this.StopNamespace();
212
- this.io = void 0;
213
- this.LogInfoMessage(`DetachServer(): attached = false`);
214
- this.attached = false;
215
- } else {
216
- const errorMessage = `DetachServer(): Error: [Server has not been attached. Use StopServer() to stop the socker.io server.]`;
217
- this.LogErrorMessage(errorMessage);
218
- throw new Error(errorMessage);
219
- }
220
- } else {
221
- const errorMessage = `DetachServer(): Error: [no server exists to DetachServer()]`;
222
- this.LogErrorMessage(errorMessage);
223
- throw new Error(errorMessage);
224
- }
225
- };
226
- StopSocketIoServer = async () => {
227
- if (this.io) {
228
- if (this.attached === false) {
229
- this.LogInfoMessage(`StopServer(): draining = true`);
230
- this.draining = true;
231
- this.LogInfoMessage(`StopServer(): StopNamespace()`);
232
- await this.StopNamespace();
233
- this.LogInfoMessage(`StopServer(): io.of('/').adapter.close()`);
234
- await this.io.of("/").adapter.close();
235
- if (this.redisClient) {
236
- this.LogInfoMessage(`StopServer(): redisClient.disconnect()`);
237
- await this.redisClient.disconnect();
238
- this.LogInfoMessage(`StopServer(): redisClient.disconnect() (Sleeping...)`);
239
- await Sleep(50);
240
- this.LogInfoMessage(`StopServer(): redisClient.disconnect() (Done Sleeping)`);
241
- }
242
- this.LogInfoMessage(`StopServer(): io.disconnectSockets()`);
243
- this.io.disconnectSockets();
244
- this.LogInfoMessage(`StopServer(): io.close()`);
245
- this.io.close();
246
- this.LogInfoMessage(`StopServer(): io = undefined`);
247
- this.io = void 0;
248
- } else {
249
- const errorMessage = `StopServer(): Cannot stop an attached server. The server created must handle stop/disconnections. Use StopNamespace() instead.`;
250
- this.LogErrorMessage(errorMessage);
251
- throw new Error(errorMessage);
252
- }
253
- } else {
254
- const errorMessage = `StopServer(): Error: [no server exists to StopServer()]`;
255
- this.LogErrorMessage(errorMessage);
256
- throw new Error(errorMessage);
257
- }
258
- };
259
- LeaveRoom = (socket, room) => {
260
- this.LogDebugMessage(`LeaveRoom(): Leaving room [${room}]`);
261
- socket.leave(room);
262
- };
263
- JoinRoom = (socket, room) => {
264
- this.LogDebugMessage(`JoinRoom(): Socket joining room [${room}], ID: [${socket.id}]`);
265
- socket.join(room);
266
- };
267
- StopNamespace = async () => {
268
- this.LogInfoMessage(`StopServer(): CloseNamespaceAdaptors()`);
269
- await this.CloseNamespaceAdaptors();
270
- this.LogInfoMessage(`StopServer(): DisconnectNamespaceSockets()`);
271
- this.DisconnectNamespaceSockets();
272
- };
273
- SetupStandardEvents = (socket) => {
274
- socket.on("disconnect", (reason) => {
275
- this.LogDebugMessage(`SetupStandardEvents(): socket disconnect, ID: [${socket.id}], reason: [${reason}]`);
276
- this.SocketDisconnect(socket, reason);
277
- });
278
- socket.on("disconnecting", (reason) => {
279
- this.LogDebugMessage(`SetupStandardEvents(): socket disconnecting, ID: [${socket.id}], reason: [${reason}]`);
280
- this.SocketDisconnecting(socket, reason);
281
- });
282
- socket.on("error", (error) => {
283
- this.LogDebugMessage(`SetupStandardEvents(): socket error, ID: [${socket.id}], Error: [${error}]`);
284
- this.SocketError(socket, error);
285
- });
286
- socket.on("__STSdisconnect", (reason) => {
287
- this.LogDebugMessage(`SetupStandardEvents(): __STSdisconnect: socket disconnect, ID: [${socket.id}], reason: [${reason}]`);
288
- });
289
- socket.on("__STSdisconnecting", (reason, callBackResult) => {
290
- this.LogDebugMessage(`SetupStandardEvents(): __STSdisconnecting: socket disconnecting, ID: [${socket.id}], reason: [${reason}]`);
291
- callBackResult("__STSdisconnecting accepted by server.");
292
- });
293
- socket.on("__STSjoinRoom", (rooms) => {
294
- rooms.forEach((room) => {
295
- this.LogDebugMessage(`SetupStandardEvents(): __STSjoinRoom: room: [${room}], socket: [${socket.id}]`);
296
- this.JoinRoom(socket, room);
297
- });
298
- });
299
- socket.on("__STSleaveRoom", (rooms) => {
300
- rooms.forEach((room) => {
301
- this.LogDebugMessage(`SetupStandardEvents(): __STSleaveRoom: room: [${room}], socket: [${socket.id}]`);
302
- this.LeaveRoom(socket, room);
303
- });
304
- });
305
- socket.on("__STSsendToRoom", (rooms, payload) => {
306
- rooms.forEach((room) => {
307
- if (this.socketionamespace) {
308
- this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoom: Sending to room [${room}], ID: [${socket.id}], Command: [${payload.command}]`);
309
- this.socketionamespace.to(room).emit(payload.command, payload);
310
- }
311
- });
312
- });
313
- socket.on("__STSsendToRoomWithCallback", (room, timeout, payload, cb) => {
314
- if (this.socketionamespace) {
315
- this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomWithCallback: Sending to room [${room}], ID: [${socket.id}], timeout: [${timeout}], Command: [${payload.command}]`);
316
- this.socketionamespace.to(room).timeout(timeout).emit(payload.command, payload, (err, dataResponse) => {
317
- if (err) {
318
- console.error(err);
319
- const errorResponse = {
320
- error: true,
321
- errorName: err.name,
322
- errorMessage: err.message
323
- //errorCause: err.cause,
324
- //errorStack: err.stack
325
- };
326
- this.LogErrorMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast (error): [${JSON.stringify(errorResponse)}]`);
327
- cb(errorResponse);
328
- } else {
329
- this.LogDebugMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast: [${JSON.stringify(dataResponse)}]`);
330
- cb(dataResponse);
331
- }
332
- });
333
- }
334
- });
335
- socket.on("__STSsendToRoomsWithCallback", (rooms, timeout, payload, cb) => {
336
- const responses = [];
337
- const timeoutForComplete = setTimeout(() => {
338
- responses.push({
339
- room: "",
340
- responses: {
341
- error: true,
342
- errorName: "timeout",
343
- errorMessage: `__STSsendToRoomsWithCallback timeout: [${timeout}] before all responses received`
344
- }
345
- });
346
- cb(responses);
347
- }, timeout).unref();
348
- rooms.forEach((room) => {
349
- if (this.socketionamespace) {
350
- this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomsWithCallback: Sending to room [${room}], ID: [${socket.id}], timeout: [${timeout}], Command: [${payload.command}]`);
351
- this.socketionamespace.to(room).timeout(timeout).emit(payload.command, payload, (err, dataResponse) => {
352
- if (err) {
353
- console.error(err);
354
- const errorResponse = {
355
- error: true,
356
- errorName: err.name,
357
- errorMessage: err.message
358
- //errorCause: err.cause,
359
- //errorStack: err.stack
360
- };
361
- this.LogErrorMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast (error): [${JSON.stringify(errorResponse)}]`);
362
- responses.push({
363
- room,
364
- responses: errorResponse
365
- });
366
- } else {
367
- this.LogDebugMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast: [${JSON.stringify(dataResponse)}]`);
368
- responses.push({
369
- room,
370
- responses: dataResponse
371
- });
372
- }
373
- if (responses.length === rooms.length) {
374
- clearTimeout(timeoutForComplete);
375
- this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomsWithCallback: All complete, Responses Count: [${responses.length}] Invoke call back(responses)`);
376
- cb(responses);
377
- }
378
- });
379
- }
380
- });
381
- });
382
- };
383
- ConnectionDrainingConnectionMiddleware = () => {
384
- if (this.socketionamespace) {
385
- this.socketionamespace.use((socket, next) => {
386
- if (this.draining === true) {
387
- next(new Error(`ConnectionDrainingConnectionMiddleware(): Error: [server connections draining (from a server disconnect)]`));
388
- } else {
389
- next();
390
- }
391
- });
392
- }
393
- };
394
- SetupNamespace = () => {
395
- if (this.io) {
396
- this.LogDebugMessage(`SetupNamespace(): socketionamespace = io.of('/${this.namespace}/'`);
397
- this.socketionamespace = this.io.of(`/${this.namespace}/`);
398
- this.LogDebugMessage(`SetupNamespace(): ConnectionDrainingConnectionMiddleware()`);
399
- this.ConnectionDrainingConnectionMiddleware();
400
- this.LogDebugMessage(`SetupNamespace(): SetupConnectionMiddleware()`);
401
- this.SetupConnectionMiddleware();
402
- this.socketionamespace.on("connection", (socket) => {
403
- this.LogDebugMessage(`SetupNamespace(): Socket connected, ID: [${socket.id}]`);
404
- this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (auth): [${JSON.stringify(socket.handshake.auth)}]`);
405
- this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (host): [${JSON.stringify(socket.handshake.headers.host)}]`);
406
- this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (url): [${JSON.stringify(socket.handshake.url)}]`);
407
- this.LogDebugMessage(`SetupNamespace(): Authentication Handshake: [${JSON.stringify(socket.handshake)}]`);
408
- this.LogDebugMessage(`SetupNamespace(): SetupMessageMiddleware(): Socket: [${socket.id}]`);
409
- this.SetupMessageMiddleware(socket);
410
- if (this.rooms && this.rooms.length > 0) {
411
- this.rooms.map((room) => {
412
- this.LogDebugMessage(`SetupNamespace(): Joining Room: [${room}], Socket: [${socket.id}]`);
413
- this.JoinRoom(socket, room);
414
- });
415
- }
416
- this.LogDebugMessage(`SetupNamespace(): SetupStandardEvents: Socket: [${socket.id}]`);
417
- this.SetupStandardEvents(socket);
418
- setTimeout(() => {
419
- this.LogDebugMessage(`SetupNamespace(): SocketConnectCallBack(): Socket: [${socket.id}]`);
420
- this.SocketConnect(socket);
421
- }, 0);
422
- this.LogDebugMessage(`SetupNamespace(): SocketEventsCallBack(): Socket: [${socket.id}]`);
423
- this.SetupSocketEvents(socket);
424
- });
425
- } else {
426
- const errorMessage = `SetupNamespace(): Error: [No server attached]`;
427
- this.LogErrorMessage(errorMessage);
428
- throw new Error(errorMessage);
429
- }
430
- return this;
431
- };
432
- CloseNamespaceAdaptors = async () => {
433
- if (this.socketionamespace) {
434
- this.LogDebugMessage(`CloseNamespaceAdaptors(): this.socketionamespace.adapter.close()`);
435
- await this.socketionamespace.adapter.close();
436
- }
437
- };
438
- DisconnectNamespaceSockets = () => {
439
- if (this.socketionamespace) {
440
- this.LogDebugMessage(`DisconnectNamespaceSockets(): this.socketionamespace.disconnectSockets()`);
441
- this.socketionamespace.disconnectSockets();
442
- this.socketionamespace = void 0;
443
- }
444
- };
445
- }
446
- export {
447
- SocketIoServer
5
+ import { createAdapter } from "@socket.io/cluster-adapter";
6
+ import { createAdapter as createAdapter$1 } from "@socket.io/redis-streams-adapter";
7
+ //#region src/socketIoServer.ts
8
+ var import_tiny_emitter = require_tiny_emitter();
9
+ var SocketIoServer = class extends import_tiny_emitter.TinyEmitter {
10
+ namespace;
11
+ socketionamespace;
12
+ logger;
13
+ io;
14
+ redisClient;
15
+ listenPort;
16
+ socketIoCustomPath;
17
+ ioRedisMessageProcessorUrl;
18
+ serverClusterMode;
19
+ rooms;
20
+ serverName;
21
+ draining = false;
22
+ attached = false;
23
+ constructor(serverName) {
24
+ super();
25
+ this.serverName = serverName;
26
+ }
27
+ get logPrefix() {
28
+ if (this.namespace) return `SocketIoServer[${this.serverName}:${this.namespace}]: `;
29
+ else return `SocketIoServer[${this.serverName}:<No Namespace>]: `;
30
+ }
31
+ LogErrorMessage(message) {
32
+ if (this.logger) this.logger.error(`${this.logPrefix}${message}`);
33
+ }
34
+ LogDebugMessage(message) {
35
+ if (this.logger) this.logger.debug(`${this.logPrefix}${message}`);
36
+ }
37
+ LogInfoMessage(message) {
38
+ if (this.logger) this.logger.info(`${this.logPrefix}${message}`);
39
+ }
40
+ LogWarnMessage(message) {
41
+ if (this.logger) this.logger.warn(`${this.logPrefix}${message}`);
42
+ }
43
+ LogSillyMessage(message) {
44
+ if (this.logger) this.logger.silly(`${this.logPrefix}${message}`);
45
+ }
46
+ LogVerboseMessage(message) {
47
+ if (this.logger) this.logger.verbose(`${this.logPrefix}${message}`);
48
+ }
49
+ LogHttpMessage(message) {
50
+ if (this.logger) this.logger.http(`${this.logPrefix}${message}`);
51
+ }
52
+ SetupConnectionMiddleware = () => {};
53
+ SetupMessageMiddleware = (socket) => {};
54
+ SetEngineEvents = () => {
55
+ if (this.io) this.io.engine.on("connection_error", (err) => {
56
+ this.LogWarnMessage(`SetEngineEvents(): connection_error`);
57
+ this.LogWarnMessage(err.req);
58
+ this.LogWarnMessage(err.code);
59
+ this.LogWarnMessage(err.message);
60
+ this.LogWarnMessage(err.context);
61
+ });
62
+ };
63
+ WithLogger = (logger) => {
64
+ this.logger = logger;
65
+ return this;
66
+ };
67
+ WithListenPort = (listenPort) => {
68
+ this.listenPort = listenPort;
69
+ return this;
70
+ };
71
+ WithSocketIoCustomPath = (socketIoCustomPath) => {
72
+ this.socketIoCustomPath = socketIoCustomPath;
73
+ return this;
74
+ };
75
+ WithIoRedisMessageProcessorUrl = (ioRedisMessageProcessorUrl) => {
76
+ this.ioRedisMessageProcessorUrl = ioRedisMessageProcessorUrl;
77
+ return this;
78
+ };
79
+ WithClusterMode = (serverClusterMode) => {
80
+ this.serverClusterMode = serverClusterMode;
81
+ return this;
82
+ };
83
+ WithRooms = (rooms) => {
84
+ this.rooms = rooms;
85
+ return this;
86
+ };
87
+ WithNamespace = (namespace) => {
88
+ this.namespace = namespace;
89
+ return this;
90
+ };
91
+ AttachSocketIoServer = async (server) => {
92
+ if (!this.io) {
93
+ this.LogInfoMessage(`AttachServer(): io = server`);
94
+ this.io = server;
95
+ this.LogInfoMessage(`AttachServer(): attached = true`);
96
+ this.attached = true;
97
+ this.LogInfoMessage(`AttachServer(): SetupNamespace()`);
98
+ this.SetupNamespace();
99
+ } else {
100
+ const errorMessage = this.attached === true ? `AttachServer(): Server already exists (from AttachServer())` : `AttachServer(): Server already exists (from StartServer())`;
101
+ this.LogErrorMessage(errorMessage);
102
+ throw new Error(errorMessage);
103
+ }
104
+ return this;
105
+ };
106
+ StartSocketIoServer = async () => {
107
+ if (!this.namespace) {
108
+ const errorMessage = `StartServer(): Error: [namespace not specified]`;
109
+ this.LogErrorMessage(errorMessage);
110
+ throw new Error(errorMessage);
111
+ }
112
+ if (!this.io) {
113
+ if (!this.listenPort) {
114
+ const errorMessage = `StartServer(): Error: [listenPort not specified]`;
115
+ this.LogErrorMessage(errorMessage);
116
+ throw new Error(errorMessage);
117
+ }
118
+ this.LogDebugMessage(`StartServer(): draining = false`);
119
+ this.draining = false;
120
+ this.LogDebugMessage(`StartServer(): transports: [ [websocket] ]`);
121
+ const options = { transports: ["websocket"] };
122
+ if (this.ioRedisMessageProcessorUrl && this.ioRedisMessageProcessorUrl !== "") {
123
+ this.redisClient = new Redis(this.ioRedisMessageProcessorUrl);
124
+ this.LogDebugMessage(`StartServer(): createAdapter(redis): redis url: [${this.ioRedisMessageProcessorUrl}]`);
125
+ options.adapter = createAdapter$1(this.redisClient);
126
+ } else if (this.serverClusterMode && this.serverClusterMode === true) {
127
+ this.LogDebugMessage(`StartServer(): createAdapter(cluster)`);
128
+ options.adapter = createAdapter();
129
+ }
130
+ if (this.socketIoCustomPath && this.socketIoCustomPath.localeCompare("") !== 0) {
131
+ this.LogDebugMessage(`StartServer(): socketIoCustomPath: [${this.socketIoCustomPath}]`);
132
+ options.path = this.socketIoCustomPath;
133
+ }
134
+ this.LogDebugMessage(`StartServer(): new Server(): listenPort: [${this.listenPort}]`);
135
+ this.io = new Server(this.listenPort, options);
136
+ this.LogDebugMessage(`StartServer(): SetEngineEvents()`);
137
+ this.SetEngineEvents();
138
+ this.LogDebugMessage(`StartServer(): Sleeping ...`);
139
+ await Sleep(500);
140
+ this.LogDebugMessage(`StartServer(): Done Sleeping`);
141
+ this.LogInfoMessage(`AttachServer(): attached = false`);
142
+ this.attached = false;
143
+ this.LogInfoMessage(`StartServer(): SetupNamespace()`);
144
+ this.SetupNamespace();
145
+ } else {
146
+ const errorMessage = this.attached === true ? `StartServer(): Server already exists (from AttachServer())` : `StartServer(): Server already exists (from StartServer())`;
147
+ this.LogErrorMessage(errorMessage);
148
+ throw new Error(errorMessage);
149
+ }
150
+ return this;
151
+ };
152
+ DetachSockerIoServer = async () => {
153
+ if (this.io) if (this.attached === true) {
154
+ this.LogInfoMessage(`DetachServer(): StopNamespace()`);
155
+ await this.StopNamespace();
156
+ this.io = void 0;
157
+ this.LogInfoMessage(`DetachServer(): attached = false`);
158
+ this.attached = false;
159
+ } else {
160
+ const errorMessage = `DetachServer(): Error: [Server has not been attached. Use StopServer() to stop the socker.io server.]`;
161
+ this.LogErrorMessage(errorMessage);
162
+ throw new Error(errorMessage);
163
+ }
164
+ else {
165
+ const errorMessage = `DetachServer(): Error: [no server exists to DetachServer()]`;
166
+ this.LogErrorMessage(errorMessage);
167
+ throw new Error(errorMessage);
168
+ }
169
+ };
170
+ StopSocketIoServer = async () => {
171
+ if (this.io) if (this.attached === false) {
172
+ this.LogInfoMessage(`StopServer(): draining = true`);
173
+ this.draining = true;
174
+ this.LogInfoMessage(`StopServer(): StopNamespace()`);
175
+ await this.StopNamespace();
176
+ this.LogInfoMessage(`StopServer(): io.of('/').adapter.close()`);
177
+ await this.io.of("/").adapter.close();
178
+ if (this.redisClient) {
179
+ this.LogInfoMessage(`StopServer(): redisClient.disconnect()`);
180
+ await this.redisClient.disconnect();
181
+ this.LogInfoMessage(`StopServer(): redisClient.disconnect() (Sleeping...)`);
182
+ await Sleep(50);
183
+ this.LogInfoMessage(`StopServer(): redisClient.disconnect() (Done Sleeping)`);
184
+ }
185
+ this.LogInfoMessage(`StopServer(): io.disconnectSockets()`);
186
+ this.io.disconnectSockets();
187
+ this.LogInfoMessage(`StopServer(): io.close()`);
188
+ this.io.close();
189
+ this.LogInfoMessage(`StopServer(): io = undefined`);
190
+ this.io = void 0;
191
+ } else {
192
+ const errorMessage = `StopServer(): Cannot stop an attached server. The server created must handle stop/disconnections. Use StopNamespace() instead.`;
193
+ this.LogErrorMessage(errorMessage);
194
+ throw new Error(errorMessage);
195
+ }
196
+ else {
197
+ const errorMessage = `StopServer(): Error: [no server exists to StopServer()]`;
198
+ this.LogErrorMessage(errorMessage);
199
+ throw new Error(errorMessage);
200
+ }
201
+ };
202
+ LeaveRoom = (socket, room) => {
203
+ this.LogDebugMessage(`LeaveRoom(): Leaving room [${room}]`);
204
+ socket.leave(room);
205
+ };
206
+ JoinRoom = (socket, room) => {
207
+ this.LogDebugMessage(`JoinRoom(): Socket joining room [${room}], ID: [${socket.id}]`);
208
+ socket.join(room);
209
+ };
210
+ StopNamespace = async () => {
211
+ this.LogInfoMessage(`StopServer(): CloseNamespaceAdaptors()`);
212
+ await this.CloseNamespaceAdaptors();
213
+ this.LogInfoMessage(`StopServer(): DisconnectNamespaceSockets()`);
214
+ this.DisconnectNamespaceSockets();
215
+ };
216
+ SetupStandardEvents = (socket) => {
217
+ socket.on("disconnect", (reason) => {
218
+ this.LogDebugMessage(`SetupStandardEvents(): socket disconnect, ID: [${socket.id}], reason: [${reason}]`);
219
+ this.SocketDisconnect(socket, reason);
220
+ });
221
+ socket.on("disconnecting", (reason) => {
222
+ this.LogDebugMessage(`SetupStandardEvents(): socket disconnecting, ID: [${socket.id}], reason: [${reason}]`);
223
+ this.SocketDisconnecting(socket, reason);
224
+ });
225
+ socket.on("error", (error) => {
226
+ this.LogDebugMessage(`SetupStandardEvents(): socket error, ID: [${socket.id}], Error: [${error}]`);
227
+ this.SocketError(socket, error);
228
+ });
229
+ socket.on("__STSdisconnect", (reason) => {
230
+ this.LogDebugMessage(`SetupStandardEvents(): __STSdisconnect: socket disconnect, ID: [${socket.id}], reason: [${reason}]`);
231
+ });
232
+ socket.on("__STSdisconnecting", (reason, callBackResult) => {
233
+ this.LogDebugMessage(`SetupStandardEvents(): __STSdisconnecting: socket disconnecting, ID: [${socket.id}], reason: [${reason}]`);
234
+ callBackResult("__STSdisconnecting accepted by server.");
235
+ });
236
+ socket.on("__STSjoinRoom", (rooms) => {
237
+ rooms.forEach((room) => {
238
+ this.LogDebugMessage(`SetupStandardEvents(): __STSjoinRoom: room: [${room}], socket: [${socket.id}]`);
239
+ this.JoinRoom(socket, room);
240
+ });
241
+ });
242
+ socket.on("__STSleaveRoom", (rooms) => {
243
+ rooms.forEach((room) => {
244
+ this.LogDebugMessage(`SetupStandardEvents(): __STSleaveRoom: room: [${room}], socket: [${socket.id}]`);
245
+ this.LeaveRoom(socket, room);
246
+ });
247
+ });
248
+ socket.on("__STSsendToRoom", (rooms, payload) => {
249
+ rooms.forEach((room) => {
250
+ if (this.socketionamespace) {
251
+ this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoom: Sending to room [${room}], ID: [${socket.id}], Command: [${payload.command}]`);
252
+ this.socketionamespace.to(room).emit(payload.command, payload);
253
+ }
254
+ });
255
+ });
256
+ socket.on("__STSsendToRoomWithCallback", (room, timeout, payload, cb) => {
257
+ if (this.socketionamespace) {
258
+ this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomWithCallback: Sending to room [${room}], ID: [${socket.id}], timeout: [${timeout}], Command: [${payload.command}]`);
259
+ this.socketionamespace.to(room).timeout(timeout).emit(payload.command, payload, (err, dataResponse) => {
260
+ if (err) {
261
+ console.error(err);
262
+ const errorResponse = {
263
+ error: true,
264
+ errorName: err.name,
265
+ errorMessage: err.message
266
+ };
267
+ this.LogErrorMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast (error): [${JSON.stringify(errorResponse)}]`);
268
+ cb(errorResponse);
269
+ } else {
270
+ this.LogDebugMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast: [${JSON.stringify(dataResponse)}]`);
271
+ cb(dataResponse);
272
+ }
273
+ });
274
+ }
275
+ });
276
+ socket.on("__STSsendToRoomsWithCallback", (rooms, timeout, payload, cb) => {
277
+ const responses = [];
278
+ const timeoutForComplete = setTimeout(() => {
279
+ responses.push({
280
+ room: "",
281
+ responses: {
282
+ error: true,
283
+ errorName: "timeout",
284
+ errorMessage: `__STSsendToRoomsWithCallback timeout: [${timeout}] before all responses received`
285
+ }
286
+ });
287
+ cb(responses);
288
+ }, timeout).unref();
289
+ rooms.forEach((room) => {
290
+ if (this.socketionamespace) {
291
+ this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomsWithCallback: Sending to room [${room}], ID: [${socket.id}], timeout: [${timeout}], Command: [${payload.command}]`);
292
+ this.socketionamespace.to(room).timeout(timeout).emit(payload.command, payload, (err, dataResponse) => {
293
+ if (err) {
294
+ console.error(err);
295
+ const errorResponse = {
296
+ error: true,
297
+ errorName: err.name,
298
+ errorMessage: err.message
299
+ };
300
+ this.LogErrorMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast (error): [${JSON.stringify(errorResponse)}]`);
301
+ responses.push({
302
+ room,
303
+ responses: errorResponse
304
+ });
305
+ } else {
306
+ this.LogDebugMessage(`SetupStandardEvents(): __STSsendToRoomWithCallback broadcast: [${JSON.stringify(dataResponse)}]`);
307
+ responses.push({
308
+ room,
309
+ responses: dataResponse
310
+ });
311
+ }
312
+ if (responses.length === rooms.length) {
313
+ clearTimeout(timeoutForComplete);
314
+ this.LogDebugMessage(`SetupStandardEvents(): socket.on: __STSsendToRoomsWithCallback: All complete, Responses Count: [${responses.length}] Invoke call back(responses)`);
315
+ cb(responses);
316
+ }
317
+ });
318
+ }
319
+ });
320
+ });
321
+ };
322
+ ConnectionDrainingConnectionMiddleware = () => {
323
+ if (this.socketionamespace) this.socketionamespace.use((socket, next) => {
324
+ if (this.draining === true) next(/* @__PURE__ */ new Error(`ConnectionDrainingConnectionMiddleware(): Error: [server connections draining (from a server disconnect)]`));
325
+ else next();
326
+ });
327
+ };
328
+ SetupNamespace = () => {
329
+ if (this.io) {
330
+ this.LogDebugMessage(`SetupNamespace(): socketionamespace = io.of('/${this.namespace}/'`);
331
+ this.socketionamespace = this.io.of(`/${this.namespace}/`);
332
+ this.LogDebugMessage(`SetupNamespace(): ConnectionDrainingConnectionMiddleware()`);
333
+ this.ConnectionDrainingConnectionMiddleware();
334
+ this.LogDebugMessage(`SetupNamespace(): SetupConnectionMiddleware()`);
335
+ this.SetupConnectionMiddleware();
336
+ this.socketionamespace.on("connection", (socket) => {
337
+ this.LogDebugMessage(`SetupNamespace(): Socket connected, ID: [${socket.id}]`);
338
+ this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (auth): [${JSON.stringify(socket.handshake.auth)}]`);
339
+ this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (host): [${JSON.stringify(socket.handshake.headers.host)}]`);
340
+ this.LogDebugMessage(`SetupNamespace(): Authentication Handshake (url): [${JSON.stringify(socket.handshake.url)}]`);
341
+ this.LogDebugMessage(`SetupNamespace(): Authentication Handshake: [${JSON.stringify(socket.handshake)}]`);
342
+ this.LogDebugMessage(`SetupNamespace(): SetupMessageMiddleware(): Socket: [${socket.id}]`);
343
+ this.SetupMessageMiddleware(socket);
344
+ if (this.rooms && this.rooms.length > 0) this.rooms.map((room) => {
345
+ this.LogDebugMessage(`SetupNamespace(): Joining Room: [${room}], Socket: [${socket.id}]`);
346
+ this.JoinRoom(socket, room);
347
+ });
348
+ this.LogDebugMessage(`SetupNamespace(): SetupStandardEvents: Socket: [${socket.id}]`);
349
+ this.SetupStandardEvents(socket);
350
+ setTimeout(() => {
351
+ this.LogDebugMessage(`SetupNamespace(): SocketConnectCallBack(): Socket: [${socket.id}]`);
352
+ this.SocketConnect(socket);
353
+ }, 0);
354
+ this.LogDebugMessage(`SetupNamespace(): SocketEventsCallBack(): Socket: [${socket.id}]`);
355
+ this.SetupSocketEvents(socket);
356
+ });
357
+ } else {
358
+ const errorMessage = `SetupNamespace(): Error: [No server attached]`;
359
+ this.LogErrorMessage(errorMessage);
360
+ throw new Error(errorMessage);
361
+ }
362
+ return this;
363
+ };
364
+ CloseNamespaceAdaptors = async () => {
365
+ if (this.socketionamespace) {
366
+ this.LogDebugMessage(`CloseNamespaceAdaptors(): this.socketionamespace.adapter.close()`);
367
+ await this.socketionamespace.adapter.close();
368
+ }
369
+ };
370
+ DisconnectNamespaceSockets = () => {
371
+ if (this.socketionamespace) {
372
+ this.LogDebugMessage(`DisconnectNamespaceSockets(): this.socketionamespace.disconnectSockets()`);
373
+ this.socketionamespace.disconnectSockets();
374
+ this.socketionamespace = void 0;
375
+ }
376
+ };
448
377
  };
449
- //# sourceMappingURL=node.mjs.map
378
+ //#endregion
379
+ export { SocketIoServer };
380
+
381
+ //# sourceMappingURL=node.mjs.map