@resolveio/server-lib 20.14.16 → 20.14.18
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/managers/subscription.manager.d.ts +5 -0
- package/managers/subscription.manager.js +144 -58
- package/managers/subscription.manager.js.map +1 -1
- package/managers/websocket.manager.d.ts +0 -1
- package/managers/websocket.manager.js +41 -111
- package/managers/websocket.manager.js.map +1 -1
- package/managers/worker-dispatcher.manager.d.ts +11 -0
- package/managers/worker-dispatcher.manager.js +136 -7
- package/managers/worker-dispatcher.manager.js.map +1 -1
- package/managers/worker-server.manager.d.ts +3 -0
- package/managers/worker-server.manager.js +126 -1
- package/managers/worker-server.manager.js.map +1 -1
- package/models/server-message.model.d.ts +2 -0
- package/models/server-message.model.js.map +1 -1
- package/package.json +1 -1
|
@@ -23,7 +23,6 @@ export declare class WebSocketManager {
|
|
|
23
23
|
send(ws: WebSocket, data: ServerResponseModel | string): void;
|
|
24
24
|
sendPackedBuffer(ws: WebSocket, messageId: number, hasError: boolean, packedData: Uint8Array | Buffer, encoding?: 'msgpack' | 'json'): void;
|
|
25
25
|
private flushMessages;
|
|
26
|
-
private sendMessagesInChunks;
|
|
27
26
|
private sendMessagesInChunksBinary;
|
|
28
27
|
private handleSendError;
|
|
29
28
|
closeConnection(ws: WebSocket): void;
|
|
@@ -59,16 +59,22 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
59
59
|
if (!this._messageBuffers.has(wsId)) {
|
|
60
60
|
this._messageBuffers.set(wsId, []);
|
|
61
61
|
}
|
|
62
|
-
var supportsBinary = ws['supportsBinary'] === true;
|
|
63
62
|
if (typeof data === 'string') {
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if (ws && ws.readyState === ws.OPEN) {
|
|
64
|
+
ws.send(data, function (error) {
|
|
65
|
+
if (error) {
|
|
66
|
+
_this.handleSendError(ws, error);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
66
71
|
}
|
|
67
72
|
else {
|
|
68
|
-
|
|
73
|
+
// Handle string messages like 'ping' or 'pong'
|
|
74
|
+
var chunkContext = this.prepareChunkContext(data);
|
|
69
75
|
if (chunkContext) {
|
|
70
76
|
this.flushMessages(ws);
|
|
71
|
-
this.sendChunkSequence(ws, data, chunkContext
|
|
77
|
+
this.sendChunkSequence(ws, data, chunkContext);
|
|
72
78
|
return;
|
|
73
79
|
}
|
|
74
80
|
this._messageBuffers.get(wsId).push(data);
|
|
@@ -88,8 +94,6 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
88
94
|
if (!ws || ws.readyState !== ws.OPEN || !packedData || !packedData.byteLength) {
|
|
89
95
|
return;
|
|
90
96
|
}
|
|
91
|
-
var supportsBinary = ws['supportsBinary'] === true;
|
|
92
|
-
var useBinary = encoding === 'msgpack' ? true : supportsBinary;
|
|
93
97
|
var chunkId = this.generateChunkId();
|
|
94
98
|
var totalChunks = Math.max(1, Math.ceil(packedData.byteLength / this._chunkSizeBytes));
|
|
95
99
|
var chunkSize = this._chunkSizeBytes;
|
|
@@ -108,7 +112,7 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
108
112
|
_a.encoding = encoding,
|
|
109
113
|
_a)
|
|
110
114
|
};
|
|
111
|
-
this.transmitBatch(ws, [startMessage]
|
|
115
|
+
this.transmitBatch(ws, [startMessage]);
|
|
112
116
|
var sendChunk = function (index) {
|
|
113
117
|
var _a, _b;
|
|
114
118
|
if (!ws || ws.readyState !== ws.OPEN) {
|
|
@@ -124,7 +128,7 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
124
128
|
_a.chunkStatus = 'end',
|
|
125
129
|
_a)
|
|
126
130
|
};
|
|
127
|
-
_this.transmitBatch(ws, [endMessage]
|
|
131
|
+
_this.transmitBatch(ws, [endMessage]);
|
|
128
132
|
return;
|
|
129
133
|
}
|
|
130
134
|
var start = index * chunkSize;
|
|
@@ -143,7 +147,7 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
143
147
|
_b.encoding = encoding,
|
|
144
148
|
_b)
|
|
145
149
|
};
|
|
146
|
-
_this.transmitBatch(ws, [chunkMessage]
|
|
150
|
+
_this.transmitBatch(ws, [chunkMessage]);
|
|
147
151
|
setImmediate(function () { return sendChunk(index + 1); });
|
|
148
152
|
};
|
|
149
153
|
setImmediate(function () { return sendChunk(0); });
|
|
@@ -151,16 +155,15 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
151
155
|
WebSocketManager.prototype.flushMessages = function (ws) {
|
|
152
156
|
var wsId = ws['id_socket'];
|
|
153
157
|
var messages = this._messageBuffers.get(wsId);
|
|
154
|
-
var supportsBinary = ws['supportsBinary'] === true;
|
|
155
158
|
if (messages && messages.length > 0) {
|
|
156
159
|
// Combine messages into one payload
|
|
157
|
-
this.transmitBatch(ws, messages
|
|
160
|
+
this.transmitBatch(ws, messages);
|
|
158
161
|
this._messageBuffers.delete(wsId);
|
|
159
162
|
clearTimeout(this._batchingTimers.get(wsId));
|
|
160
163
|
this._batchingTimers.delete(wsId);
|
|
161
164
|
}
|
|
162
165
|
};
|
|
163
|
-
WebSocketManager.prototype.
|
|
166
|
+
WebSocketManager.prototype.sendMessagesInChunksBinary = function (ws, messages) {
|
|
164
167
|
var e_1, _a;
|
|
165
168
|
var _this = this;
|
|
166
169
|
var chunk = [];
|
|
@@ -168,16 +171,15 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
168
171
|
try {
|
|
169
172
|
for (var messages_1 = __values(messages), messages_1_1 = messages_1.next(); !messages_1_1.done; messages_1_1 = messages_1.next()) {
|
|
170
173
|
var message = messages_1_1.value;
|
|
171
|
-
var
|
|
172
|
-
var messageSize =
|
|
174
|
+
var packedMessage = Buffer.from((0, msgpackr_1.pack)([message]));
|
|
175
|
+
var messageSize = packedMessage.byteLength;
|
|
173
176
|
if (chunkSize + messageSize > this._maxMessageSize) {
|
|
174
|
-
|
|
175
|
-
ws.send(
|
|
177
|
+
var packedChunk = Buffer.from((0, msgpackr_1.pack)(chunk));
|
|
178
|
+
ws.send(packedChunk, function (error) {
|
|
176
179
|
if (error) {
|
|
177
180
|
_this.handleSendError(ws, error);
|
|
178
181
|
}
|
|
179
182
|
});
|
|
180
|
-
// Start new chunk
|
|
181
183
|
chunk = [message];
|
|
182
184
|
chunkSize = messageSize;
|
|
183
185
|
}
|
|
@@ -194,50 +196,8 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
194
196
|
}
|
|
195
197
|
finally { if (e_1) throw e_1.error; }
|
|
196
198
|
}
|
|
197
|
-
// Send any remaining messages
|
|
198
|
-
if (chunk.length > 0) {
|
|
199
|
-
ws.send(JSON.stringify(chunk), function (error) {
|
|
200
|
-
if (error) {
|
|
201
|
-
_this.handleSendError(ws, error);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
WebSocketManager.prototype.sendMessagesInChunksBinary = function (ws, messages) {
|
|
207
|
-
var e_2, _a;
|
|
208
|
-
var _this = this;
|
|
209
|
-
var chunk = [];
|
|
210
|
-
var chunkSize = 0;
|
|
211
|
-
try {
|
|
212
|
-
for (var messages_2 = __values(messages), messages_2_1 = messages_2.next(); !messages_2_1.done; messages_2_1 = messages_2.next()) {
|
|
213
|
-
var message = messages_2_1.value;
|
|
214
|
-
var packedMessage = (0, msgpackr_1.pack)([message]);
|
|
215
|
-
var messageSize = packedMessage.byteLength;
|
|
216
|
-
if (chunkSize + messageSize > this._maxMessageSize) {
|
|
217
|
-
var packedChunk = (0, msgpackr_1.pack)(chunk);
|
|
218
|
-
ws.send(packedChunk, function (error) {
|
|
219
|
-
if (error) {
|
|
220
|
-
_this.handleSendError(ws, error);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
chunk = [message];
|
|
224
|
-
chunkSize = messageSize;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
chunk.push(message);
|
|
228
|
-
chunkSize += messageSize;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
233
|
-
finally {
|
|
234
|
-
try {
|
|
235
|
-
if (messages_2_1 && !messages_2_1.done && (_a = messages_2.return)) _a.call(messages_2);
|
|
236
|
-
}
|
|
237
|
-
finally { if (e_2) throw e_2.error; }
|
|
238
|
-
}
|
|
239
199
|
if (chunk.length > 0) {
|
|
240
|
-
var packedChunk = (0, msgpackr_1.pack)(chunk);
|
|
200
|
+
var packedChunk = Buffer.from((0, msgpackr_1.pack)(chunk));
|
|
241
201
|
ws.send(packedChunk, function (error) {
|
|
242
202
|
if (error) {
|
|
243
203
|
_this.handleSendError(ws, error);
|
|
@@ -271,7 +231,7 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
271
231
|
}
|
|
272
232
|
});
|
|
273
233
|
};
|
|
274
|
-
WebSocketManager.prototype.prepareChunkContext = function (message
|
|
234
|
+
WebSocketManager.prototype.prepareChunkContext = function (message) {
|
|
275
235
|
var _a;
|
|
276
236
|
if (!message || message.hasError) {
|
|
277
237
|
return null;
|
|
@@ -281,36 +241,22 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
281
241
|
return null;
|
|
282
242
|
}
|
|
283
243
|
try {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return { buffer: packed, encoding: 'msgpack' };
|
|
288
|
-
}
|
|
244
|
+
var packed = Buffer.from((0, msgpackr_1.pack)(data));
|
|
245
|
+
if (packed.byteLength > this._chunkThresholdBytes) {
|
|
246
|
+
return { buffer: packed, encoding: 'msgpack' };
|
|
289
247
|
}
|
|
290
248
|
}
|
|
291
249
|
catch (err) {
|
|
292
|
-
// Fall back to JSON chunking if msgpack encoding fails
|
|
293
250
|
if ((_a = this._mainServer.getSubscriptionManager()) === null || _a === void 0 ? void 0 : _a.getEnableDebug()) {
|
|
294
|
-
console.log(new Date(), 'WebSocketManager', 'Chunking pack failed
|
|
251
|
+
console.log(new Date(), 'WebSocketManager', 'Chunking pack failed', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
295
252
|
}
|
|
296
253
|
}
|
|
297
|
-
try {
|
|
298
|
-
var jsonString = JSON.stringify(data);
|
|
299
|
-
var jsonBytes = Buffer.byteLength(jsonString, 'utf8');
|
|
300
|
-
if (jsonBytes > this._chunkThresholdBytes) {
|
|
301
|
-
return { buffer: Buffer.from(jsonString, 'utf8'), encoding: 'json' };
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
catch (_b) {
|
|
305
|
-
// Ignore JSON stringify errors; fallback to normal send
|
|
306
|
-
}
|
|
307
254
|
return null;
|
|
308
255
|
};
|
|
309
|
-
WebSocketManager.prototype.sendChunkSequence = function (ws, original, chunkContext
|
|
256
|
+
WebSocketManager.prototype.sendChunkSequence = function (ws, original, chunkContext) {
|
|
310
257
|
var _a, _b, _c;
|
|
311
258
|
var chunkId = this.generateChunkId();
|
|
312
259
|
var totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);
|
|
313
|
-
var useBinary = supportsBinary && chunkContext.encoding === 'msgpack';
|
|
314
260
|
var startMessage = {
|
|
315
261
|
messageId: original.messageId,
|
|
316
262
|
hasError: original.hasError,
|
|
@@ -324,12 +270,12 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
324
270
|
_a.encoding = chunkContext.encoding,
|
|
325
271
|
_a)
|
|
326
272
|
};
|
|
327
|
-
this.transmitBatch(ws, [startMessage]
|
|
273
|
+
this.transmitBatch(ws, [startMessage]);
|
|
328
274
|
for (var index = 0; index < totalChunks; index++) {
|
|
329
275
|
var start = index * this._chunkSizeBytes;
|
|
330
276
|
var end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);
|
|
331
277
|
var slice = chunkContext.buffer.subarray(start, end);
|
|
332
|
-
var chunkPayload =
|
|
278
|
+
var chunkPayload = slice;
|
|
333
279
|
var chunkMessage = {
|
|
334
280
|
messageId: original.messageId,
|
|
335
281
|
hasError: original.hasError,
|
|
@@ -342,7 +288,7 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
342
288
|
_b.encoding = chunkContext.encoding,
|
|
343
289
|
_b)
|
|
344
290
|
};
|
|
345
|
-
this.transmitBatch(ws, [chunkMessage]
|
|
291
|
+
this.transmitBatch(ws, [chunkMessage]);
|
|
346
292
|
}
|
|
347
293
|
var endMessage = {
|
|
348
294
|
messageId: original.messageId,
|
|
@@ -353,42 +299,26 @@ var WebSocketManager = /** @class */ (function () {
|
|
|
353
299
|
_c.chunkStatus = 'end',
|
|
354
300
|
_c)
|
|
355
301
|
};
|
|
356
|
-
this.transmitBatch(ws, [endMessage]
|
|
302
|
+
this.transmitBatch(ws, [endMessage]);
|
|
357
303
|
};
|
|
358
|
-
WebSocketManager.prototype.transmitBatch = function (ws, batch
|
|
304
|
+
WebSocketManager.prototype.transmitBatch = function (ws, batch) {
|
|
359
305
|
var _this = this;
|
|
360
306
|
var _a;
|
|
361
307
|
if (!batch || !batch.length) {
|
|
362
308
|
return;
|
|
363
309
|
}
|
|
364
310
|
var isChunkEnvelope = batch.length === 1 && ((_a = batch[0]) === null || _a === void 0 ? void 0 : _a.data) && typeof batch[0].data === 'object' && batch[0].data[this._chunkMetaFlag];
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
this.sendMessagesInChunksBinary(ws, batch);
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
ws.send(packedData, function (error) {
|
|
373
|
-
if (error) {
|
|
374
|
-
_this.handleSendError(ws, error);
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
}
|
|
311
|
+
var packedData = Buffer.from((0, msgpackr_1.pack)(batch));
|
|
312
|
+
var dataSize = packedData.byteLength;
|
|
313
|
+
if (!isChunkEnvelope && dataSize > this._maxMessageSize) {
|
|
314
|
+
this.sendMessagesInChunksBinary(ws, batch);
|
|
378
315
|
}
|
|
379
316
|
else {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
ws.send(combinedData, function (error) {
|
|
387
|
-
if (error) {
|
|
388
|
-
_this.handleSendError(ws, error);
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
}
|
|
317
|
+
ws.send(packedData, function (error) {
|
|
318
|
+
if (error) {
|
|
319
|
+
_this.handleSendError(ws, error);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
392
322
|
}
|
|
393
323
|
};
|
|
394
324
|
WebSocketManager.prototype.generateChunkId = function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":[],"mappings":"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","file":"websocket.manager.js","sourcesContent":["import { randomBytes } from 'crypto';\nimport { pack } from 'msgpackr';\nimport { WebSocket } from 'ws';\n\ninterface ServerResponseModel {\n\tmessageId: number;\n\thasError: boolean;\n\tdata: any;\n}\n\nexport class WebSocketManager {\n\tprivate _mainServer;\n\tprivate _messageBuffers: Map<string, ServerResponseModel[]> = new Map();\n\tprivate _batchingTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _maxMessageSize: number;\n\tprivate _messageDelay: number;\n\tprivate _webSockets: Map<string, WebSocket> = new Map();\n\tprivate _chunkThresholdBytes: number;\n\tprivate _chunkSizeBytes: number;\n\tprivate readonly _chunkMetaFlag = '__chunked';\n\n\tconstructor() {}\n\t\n\tstatic create(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 512 * 1024, chunkSizeBytes: number = 1024 * 1024) {\n\t\tconst websocketManager = new WebSocketManager();\n\t\twebsocketManager.initialize(mainServer, maxMessageSize, messageDelay, chunkThresholdBytes, chunkSizeBytes);\n\t\treturn websocketManager;\n\t}\n\n\tpublic initialize(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 3 * 1024 * 1024, chunkSizeBytes: number = 4 * 1024 * 1024) {\n\t\tthis._mainServer = mainServer;\n\t\tthis._maxMessageSize = maxMessageSize;\n\t\tthis._messageDelay = messageDelay;\n\t\tthis._chunkThresholdBytes = chunkThresholdBytes;\n\t\tthis._chunkSizeBytes = chunkSizeBytes;\n\t}\n\n\tpublic addWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.set(wsId, ws);\n\t}\n\n\tpublic removeWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.delete(wsId);\n\t\tthis.closeConnection(ws);\n\t}\n\n\tpublic getWebSocket(id_socket: string): WebSocket | undefined {\n\t\treturn this._webSockets.get(id_socket);\n\t}\n\n\tpublic send(ws: WebSocket, data: ServerResponseModel | string): void {\n\t\tconst wsId = ws['id_socket'];\n\n\t\tif (!this._messageBuffers.has(wsId)) {\n\t\t\tthis._messageBuffers.set(wsId, []);\n\t\t}\n\n\t\tconst supportsBinary = ws['supportsBinary'] === true;\n\n\t\tif (typeof data === 'string') {\n\t\t\t// Handle string messages like 'ping' or 'pong'\n\t\t\tthis._messageBuffers.get(wsId).push({ messageId: null, hasError: false, data: data });\n\t\t}\n\t\telse {\n\t\t\tconst chunkContext = this.prepareChunkContext(data, supportsBinary);\n\t\t\tif (chunkContext) {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t\tthis.sendChunkSequence(ws, data, chunkContext, supportsBinary);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._messageBuffers.get(wsId).push(data);\n\t\t}\n\n\t\tif (!this._batchingTimers.has(wsId)) {\n\t\t\t// Set a timer to send the batch after a short delay\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t}, this._messageDelay);\n\t\t\tthis._batchingTimers.set(wsId, timer);\n\t\t}\n\t}\n\n\tpublic sendPackedBuffer(ws: WebSocket, messageId: number, hasError: boolean, packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json' = 'msgpack'): void {\n\t\tif (!ws || ws.readyState !== ws.OPEN || !packedData || !packedData.byteLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst supportsBinary = ws['supportsBinary'] === true;\n\t\tconst useBinary = encoding === 'msgpack' ? true : supportsBinary;\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.max(1, Math.ceil(packedData.byteLength / this._chunkSizeBytes));\n\t\tconst chunkSize = this._chunkSizeBytes;\n\n\t\t// Flush any buffered messages so the chunk stream starts immediately.\n\t\tthis.flushMessages(ws);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\tchunkSize: chunkSize,\n\t\t\t\tencoding: encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage], useBinary);\n\n\t\tconst sendChunk = (index: number) => {\n\t\t\tif (!ws || ws.readyState !== ws.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= totalChunks) {\n\t\t\t\tconst endMessage: ServerResponseModel = {\n\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\thasError: hasError,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\t\tchunkStatus: 'end'\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.transmitBatch(ws, [endMessage], useBinary);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst start = index * chunkSize;\n\t\t\tconst end = Math.min(packedData.byteLength, start + chunkSize);\n\t\t\tconst slice = packedData.subarray(start, end);\n\t\t\tconst payload = encoding === 'msgpack' ? slice : this.toBase64(slice);\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: payload,\n\t\t\t\t\tencoding: encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage], useBinary);\n\n\t\t\tsetImmediate(() => sendChunk(index + 1));\n\t\t};\n\n\t\tsetImmediate(() => sendChunk(0));\n\t}\n\n\tprivate flushMessages(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst messages = this._messageBuffers.get(wsId);\n\t\tconst supportsBinary = ws['supportsBinary'] === true;\n\n\t\tif (messages && messages.length > 0) {\n\t\t\t// Combine messages into one payload\n\t\t\tthis.transmitBatch(ws, messages, supportsBinary);\n\n\t\t\tthis._messageBuffers.delete(wsId);\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunks(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst messageData = JSON.stringify([message]); // Wrap message in array for consistency\n\t\t\tconst messageSize = Buffer.byteLength(messageData, 'utf8');\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\t// Send current chunk\n\t\t\t\tws.send(JSON.stringify(chunk), (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Start new chunk\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\t// Send any remaining messages\n\t\tif (chunk.length > 0) {\n\t\t\tws.send(JSON.stringify(chunk), (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunksBinary(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst packedMessage = pack([message]);\n\t\t\tconst messageSize = packedMessage.byteLength;\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\tconst packedChunk = pack(chunk);\n\t\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\tif (chunk.length > 0) {\n\t\t\tconst packedChunk = pack(chunk);\n\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleSendError(ws: WebSocket, error: Error): void {\n\t\tif (this._mainServer.getSubscriptionManager()) {\n\t\t\t// Handle send error, e.g., unsubscribe, close connection\n\t\t\tif (this._mainServer.getSubscriptionManager().getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Unsub WS', ws['user'], ws['id_socket'], error);\n\t\t\t}\n\t\t\tthis._mainServer.getSubscriptionManager().unsubscribeAll(ws);\n\t\t\tthis.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic closeConnection(ws: WebSocket): void {\n\t\tws.close();\n\t\tconst wsId = ws['id_socket'];\n\t\t// Clean up buffers and timers\n\t\tthis._messageBuffers.delete(wsId);\n\t\tif (this._batchingTimers.has(wsId)) {\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n \n process.nextTick(() => {\n if ([ws.OPEN, ws.CLOSING].includes(<any>ws.readyState)) {\n // Socket still hangs, hard close\n ws.terminate();\n }\n });\n\t}\n\n\tprivate prepareChunkContext(message: ServerResponseModel, supportsBinary: boolean): { buffer: Buffer, encoding: 'msgpack' | 'json' } | null {\n\t\tif (!message || message.hasError) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = message.data;\n\t\tif (data === undefined || data === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tif (supportsBinary) {\n\t\t\t\tconst packed = Buffer.from(<any>pack(data));\n\t\t\t\tif (packed.byteLength > this._chunkThresholdBytes) {\n\t\t\t\t\treturn { buffer: packed, encoding: 'msgpack' };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\t// Fall back to JSON chunking if msgpack encoding fails\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Chunking pack failed, falling back to JSON', err?.message || err);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst jsonString = JSON.stringify(data);\n\t\t\tconst jsonBytes = Buffer.byteLength(jsonString, 'utf8');\n\n\t\t\tif (jsonBytes > this._chunkThresholdBytes) {\n\t\t\t\treturn { buffer: Buffer.from(jsonString, 'utf8'), encoding: 'json' };\n\t\t\t}\n\t\t}\n\t\tcatch {\n\t\t\t// Ignore JSON stringify errors; fallback to normal send\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate sendChunkSequence(ws: WebSocket, original: ServerResponseModel, chunkContext: { buffer: Buffer, encoding: 'msgpack' | 'json' }, supportsBinary: boolean): void {\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);\n\t\tconst useBinary = supportsBinary && chunkContext.encoding === 'msgpack';\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: chunkContext.buffer.byteLength,\n\t\t\t\tchunkSize: this._chunkSizeBytes,\n\t\t\t\tencoding: chunkContext.encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage], useBinary);\n\n\t\tfor (let index = 0; index < totalChunks; index++) {\n\t\t\tconst start = index * this._chunkSizeBytes;\n\t\t\tconst end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);\n\t\t\tconst slice = chunkContext.buffer.subarray(start, end);\n\t\t\tconst chunkPayload = chunkContext.encoding === 'msgpack' ? slice : slice.toString('base64');\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: original.messageId,\n\t\t\t\thasError: original.hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: chunkPayload,\n\t\t\t\t\tencoding: chunkContext.encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage], useBinary);\n\t\t}\n\n\t\tconst endMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'end'\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [endMessage], useBinary);\n\t}\n\n\tprivate transmitBatch(ws: WebSocket, batch: ServerResponseModel[], useBinary: boolean): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isChunkEnvelope = batch.length === 1 && batch[0]?.data && typeof batch[0].data === 'object' && batch[0].data[this._chunkMetaFlag];\n\n\t\tif (useBinary) {\n\t\t\tconst packedData = pack(batch);\n\t\t\tconst dataSize = packedData.byteLength;\n\n\t\t\tif (!isChunkEnvelope && dataSize > this._maxMessageSize) {\n\t\t\t\tthis.sendMessagesInChunksBinary(ws, batch);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tws.send(packedData, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tconst combinedData = JSON.stringify(batch);\n\t\t\tconst dataSize = Buffer.byteLength(combinedData, 'utf8');\n\n\t\t\tif (!isChunkEnvelope && dataSize > this._maxMessageSize) {\n\t\t\t\tthis.sendMessagesInChunks(ws, batch);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tws.send(combinedData, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate generateChunkId(): string {\n\t\treturn randomBytes(8).toString('hex');\n\t}\n\n\tprivate toBase64(data: Uint8Array | Buffer): string {\n\t\tif (Buffer.isBuffer(data)) {\n\t\t\treturn data.toString('base64');\n\t\t}\n\n\t\treturn Buffer.from(data).toString('base64');\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":[],"mappings":"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","file":"websocket.manager.js","sourcesContent":["import { randomBytes } from 'crypto';\nimport { pack } from 'msgpackr';\nimport { WebSocket } from 'ws';\n\ninterface ServerResponseModel {\n\tmessageId: number;\n\thasError: boolean;\n\tdata: any;\n}\n\nexport class WebSocketManager {\n\tprivate _mainServer;\n\tprivate _messageBuffers: Map<string, ServerResponseModel[]> = new Map();\n\tprivate _batchingTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _maxMessageSize: number;\n\tprivate _messageDelay: number;\n\tprivate _webSockets: Map<string, WebSocket> = new Map();\n\tprivate _chunkThresholdBytes: number;\n\tprivate _chunkSizeBytes: number;\n\tprivate readonly _chunkMetaFlag = '__chunked';\n\n\tconstructor() {}\n\t\n\tstatic create(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 512 * 1024, chunkSizeBytes: number = 1024 * 1024) {\n\t\tconst websocketManager = new WebSocketManager();\n\t\twebsocketManager.initialize(mainServer, maxMessageSize, messageDelay, chunkThresholdBytes, chunkSizeBytes);\n\t\treturn websocketManager;\n\t}\n\n\tpublic initialize(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25, chunkThresholdBytes: number = 3 * 1024 * 1024, chunkSizeBytes: number = 4 * 1024 * 1024) {\n\t\tthis._mainServer = mainServer;\n\t\tthis._maxMessageSize = maxMessageSize;\n\t\tthis._messageDelay = messageDelay;\n\t\tthis._chunkThresholdBytes = chunkThresholdBytes;\n\t\tthis._chunkSizeBytes = chunkSizeBytes;\n\t}\n\n\tpublic addWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.set(wsId, ws);\n\t}\n\n\tpublic removeWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.delete(wsId);\n\t\tthis.closeConnection(ws);\n\t}\n\n\tpublic getWebSocket(id_socket: string): WebSocket | undefined {\n\t\treturn this._webSockets.get(id_socket);\n\t}\n\n\tpublic send(ws: WebSocket, data: ServerResponseModel | string): void {\n\t\tconst wsId = ws['id_socket'];\n\n\t\tif (!this._messageBuffers.has(wsId)) {\n\t\t\tthis._messageBuffers.set(wsId, []);\n\t\t}\n\n\t\tif (typeof data === 'string') {\n\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\tws.send(data, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\t// Handle string messages like 'ping' or 'pong'\n\t\t\tconst chunkContext = this.prepareChunkContext(data);\n\t\t\tif (chunkContext) {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t\tthis.sendChunkSequence(ws, data, chunkContext);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._messageBuffers.get(wsId).push(data);\n\t\t}\n\n\t\tif (!this._batchingTimers.has(wsId)) {\n\t\t\t// Set a timer to send the batch after a short delay\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t}, this._messageDelay);\n\t\t\tthis._batchingTimers.set(wsId, timer);\n\t\t}\n\t}\n\n\tpublic sendPackedBuffer(ws: WebSocket, messageId: number, hasError: boolean, packedData: Uint8Array | Buffer, encoding: 'msgpack' | 'json' = 'msgpack'): void {\n\t\tif (!ws || ws.readyState !== ws.OPEN || !packedData || !packedData.byteLength) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.max(1, Math.ceil(packedData.byteLength / this._chunkSizeBytes));\n\t\tconst chunkSize = this._chunkSizeBytes;\n\n\t\t// Flush any buffered messages so the chunk stream starts immediately.\n\t\tthis.flushMessages(ws);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: messageId,\n\t\t\thasError: hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: packedData.byteLength,\n\t\t\t\tchunkSize: chunkSize,\n\t\t\t\tencoding: encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tconst sendChunk = (index: number) => {\n\t\t\tif (!ws || ws.readyState !== ws.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= totalChunks) {\n\t\t\t\tconst endMessage: ServerResponseModel = {\n\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\thasError: hasError,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\t\tchunkStatus: 'end'\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.transmitBatch(ws, [endMessage]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst start = index * chunkSize;\n\t\t\tconst end = Math.min(packedData.byteLength, start + chunkSize);\n\t\t\tconst slice = packedData.subarray(start, end);\n\t\t\tconst payload = encoding === 'msgpack' ? slice : this.toBase64(slice);\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: payload,\n\t\t\t\t\tencoding: encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\n\t\t\tsetImmediate(() => sendChunk(index + 1));\n\t\t};\n\n\t\tsetImmediate(() => sendChunk(0));\n\t}\n\n\tprivate flushMessages(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst messages = this._messageBuffers.get(wsId);\n\n\t\tif (messages && messages.length > 0) {\n\t\t\t// Combine messages into one payload\n\t\t\tthis.transmitBatch(ws, messages);\n\n\t\t\tthis._messageBuffers.delete(wsId);\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunksBinary(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst packedMessage = Buffer.from(<any>pack([message]));\n\t\t\tconst messageSize = packedMessage.byteLength;\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\tif (chunk.length > 0) {\n\t\t\tconst packedChunk = Buffer.from(<any>pack(chunk));\n\t\t\tws.send(packedChunk, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleSendError(ws: WebSocket, error: Error): void {\n\t\tif (this._mainServer.getSubscriptionManager()) {\n\t\t\t// Handle send error, e.g., unsubscribe, close connection\n\t\t\tif (this._mainServer.getSubscriptionManager().getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Unsub WS', ws['user'], ws['id_socket'], error);\n\t\t\t}\n\t\t\tthis._mainServer.getSubscriptionManager().unsubscribeAll(ws);\n\t\t\tthis.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic closeConnection(ws: WebSocket): void {\n\t\tws.close();\n\t\tconst wsId = ws['id_socket'];\n\t\t// Clean up buffers and timers\n\t\tthis._messageBuffers.delete(wsId);\n\t\tif (this._batchingTimers.has(wsId)) {\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n \n process.nextTick(() => {\n if ([ws.OPEN, ws.CLOSING].includes(<any>ws.readyState)) {\n // Socket still hangs, hard close\n ws.terminate();\n }\n });\n\t}\n\n\tprivate prepareChunkContext(message: ServerResponseModel): { buffer: Buffer, encoding: 'msgpack' | 'json' } | null {\n\t\tif (!message || message.hasError) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = message.data;\n\t\tif (data === undefined || data === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tconst packed = Buffer.from(<any>pack(data));\n\t\t\tif (packed.byteLength > this._chunkThresholdBytes) {\n\t\t\t\treturn { buffer: packed, encoding: 'msgpack' };\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tif (this._mainServer.getSubscriptionManager()?.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Chunking pack failed', err?.message || err);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate sendChunkSequence(ws: WebSocket, original: ServerResponseModel, chunkContext: { buffer: Buffer, encoding: 'msgpack' | 'json' }): void {\n\t\tconst chunkId = this.generateChunkId();\n\t\tconst totalChunks = Math.ceil(chunkContext.buffer.byteLength / this._chunkSizeBytes);\n\n\t\tconst startMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'start',\n\t\t\t\ttotalChunks: totalChunks,\n\t\t\t\ttotalBytes: chunkContext.buffer.byteLength,\n\t\t\t\tchunkSize: this._chunkSizeBytes,\n\t\t\t\tencoding: chunkContext.encoding\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [startMessage]);\n\n\t\tfor (let index = 0; index < totalChunks; index++) {\n\t\t\tconst start = index * this._chunkSizeBytes;\n\t\t\tconst end = Math.min(chunkContext.buffer.byteLength, start + this._chunkSizeBytes);\n\t\t\tconst slice = chunkContext.buffer.subarray(start, end);\n\t\t\tconst chunkPayload = slice;\n\n\t\t\tconst chunkMessage: ServerResponseModel = {\n\t\t\t\tmessageId: original.messageId,\n\t\t\t\thasError: original.hasError,\n\t\t\t\tdata: {\n\t\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\t\tchunkId: chunkId,\n\t\t\t\t\tchunkStatus: 'chunk',\n\t\t\t\t\tchunkIndex: index,\n\t\t\t\t\tpayload: chunkPayload,\n\t\t\t\t\tencoding: chunkContext.encoding\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.transmitBatch(ws, [chunkMessage]);\n\t\t}\n\n\t\tconst endMessage: ServerResponseModel = {\n\t\t\tmessageId: original.messageId,\n\t\t\thasError: original.hasError,\n\t\t\tdata: {\n\t\t\t\t[this._chunkMetaFlag]: true,\n\t\t\t\tchunkId: chunkId,\n\t\t\t\tchunkStatus: 'end'\n\t\t\t}\n\t\t};\n\n\t\tthis.transmitBatch(ws, [endMessage]);\n\t}\n\n\tprivate transmitBatch(ws: WebSocket, batch: ServerResponseModel[]): void {\n\t\tif (!batch || !batch.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isChunkEnvelope = batch.length === 1 && batch[0]?.data && typeof batch[0].data === 'object' && batch[0].data[this._chunkMetaFlag];\n\n\t\tconst packedData = Buffer.from(<any>pack(batch));\n\t\tconst dataSize = packedData.byteLength;\n\n\t\tif (!isChunkEnvelope && dataSize > this._maxMessageSize) {\n\t\t\tthis.sendMessagesInChunksBinary(ws, batch);\n\t\t}\n\t\telse {\n\t\t\tws.send(packedData, (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate generateChunkId(): string {\n\t\treturn randomBytes(8).toString('hex');\n\t}\n\n\tprivate toBase64(data: Uint8Array | Buffer): string {\n\t\tif (Buffer.isBuffer(data)) {\n\t\t\treturn data.toString('base64');\n\t\t}\n\n\t\treturn Buffer.from(data).toString('base64');\n\t}\n}\n"]}
|
|
@@ -9,6 +9,13 @@ export interface WorkerConnection {
|
|
|
9
9
|
taskId: string;
|
|
10
10
|
weight: number;
|
|
11
11
|
method?: string;
|
|
12
|
+
startedAt?: number;
|
|
13
|
+
messageId?: number;
|
|
14
|
+
userContext?: {
|
|
15
|
+
id_user?: string;
|
|
16
|
+
user?: string;
|
|
17
|
+
id_ws?: string;
|
|
18
|
+
};
|
|
12
19
|
}[];
|
|
13
20
|
workerIndex?: string;
|
|
14
21
|
workerInstance?: string;
|
|
@@ -21,7 +28,9 @@ export declare class WorkerDispatcherManager {
|
|
|
21
28
|
private _clientRequests;
|
|
22
29
|
private _pendingTasks;
|
|
23
30
|
private _debugNoWorkerTaskIds;
|
|
31
|
+
private _taskTimings;
|
|
24
32
|
private MAX_CONCURRENCY;
|
|
33
|
+
private WORKER_TASK_LOG_THRESHOLD_MS;
|
|
25
34
|
constructor();
|
|
26
35
|
static create(websocketManager: WebSocketManager, methodManager: MethodManager): WorkerDispatcherManager;
|
|
27
36
|
initialize(websocketManager: WebSocketManager, methodManager: MethodManager): void;
|
|
@@ -72,6 +81,8 @@ export declare class WorkerDispatcherManager {
|
|
|
72
81
|
private assignTaskToWorker;
|
|
73
82
|
private logNoWorkerAvailability;
|
|
74
83
|
private shouldDebug;
|
|
84
|
+
private logWorkerEvent;
|
|
85
|
+
private safeStringify;
|
|
75
86
|
/**
|
|
76
87
|
* Handle messages coming back from a worker (like 'taskComplete').
|
|
77
88
|
*/
|