@nsshunt/stssocketioutils 2.0.32 → 2.0.34

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