livedesk 0.1.118 → 0.1.119
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/hub/src/remote-hub.js
CHANGED
|
@@ -122,6 +122,8 @@ const DEFAULT_PUBLIC_IP_TIMEOUT_MS = 1800;
|
|
|
122
122
|
const DUPLICATE_DEVICE_ACTIVE_REJECT_MS = 15000;
|
|
123
123
|
const DUPLICATE_DEVICE_LOG_THROTTLE_MS = 60000;
|
|
124
124
|
const DUPLICATE_DEVICE_RETRY_AFTER_MS = 30000;
|
|
125
|
+
const AGENT_BINARY_INGRESS_QUEUE_PACKETS = 18;
|
|
126
|
+
const AGENT_BINARY_INGRESS_DRAIN_BUDGET_PACKETS = 64;
|
|
125
127
|
const SYNTHETIC_FRAME_DATA_URL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAADElEQVR42mP8z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC';
|
|
126
128
|
const SYNTHETIC_FRAME_PAYLOAD = Buffer.from(SYNTHETIC_FRAME_DATA_URL.split(',')[1], 'base64');
|
|
127
129
|
const SYNTHETIC_FRAME_HASH = crypto.createHash('sha256').update(SYNTHETIC_FRAME_PAYLOAD).digest('hex').slice(0, 16);
|
|
@@ -3178,6 +3180,64 @@ export function createRemoteHub(options = {}) {
|
|
|
3178
3180
|
});
|
|
3179
3181
|
}
|
|
3180
3182
|
|
|
3183
|
+
function dropQueuedAgentBinaryFrame(state) {
|
|
3184
|
+
if (!Array.isArray(state.binaryQueue) || state.binaryQueue.length === 0) {
|
|
3185
|
+
return;
|
|
3186
|
+
}
|
|
3187
|
+
const deltaIndex = state.binaryQueue.findIndex(item => {
|
|
3188
|
+
const header = item?.header || {};
|
|
3189
|
+
const frameKind = safeString(header.frameKind || header.kind || header.frameType || '', 40).toLowerCase();
|
|
3190
|
+
const chunkType = safeString(header.chunkType, 20).toLowerCase();
|
|
3191
|
+
return (frameKind === 'stream' || frameKind === 'live' || header.type === 'stream.binary')
|
|
3192
|
+
&& header.isKeyFrame !== true
|
|
3193
|
+
&& chunkType !== 'key';
|
|
3194
|
+
});
|
|
3195
|
+
const index = deltaIndex >= 0 ? deltaIndex : 0;
|
|
3196
|
+
state.binaryQueue.splice(index, 1);
|
|
3197
|
+
state.binaryQueueDrops = Number(state.binaryQueueDrops || 0) + 1;
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
function drainQueuedAgentBinaryFrames(socket, state) {
|
|
3201
|
+
if (state.binaryQueueDraining || state.closed) {
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
state.binaryQueueDraining = true;
|
|
3205
|
+
setImmediate(() => {
|
|
3206
|
+
state.binaryQueueDraining = false;
|
|
3207
|
+
if (state.closed || socket.destroyed) {
|
|
3208
|
+
state.binaryQueue.length = 0;
|
|
3209
|
+
return;
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
let processed = 0;
|
|
3213
|
+
while (state.binaryQueue.length > 0 && processed < AGENT_BINARY_INGRESS_DRAIN_BUDGET_PACKETS) {
|
|
3214
|
+
const item = state.binaryQueue.shift();
|
|
3215
|
+
if (item) {
|
|
3216
|
+
handleAgentBinaryFrame(socket, state, item.header, item.payload);
|
|
3217
|
+
processed += 1;
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
if (state.binaryQueue.length > 0 && !state.closed && !socket.destroyed) {
|
|
3222
|
+
drainQueuedAgentBinaryFrames(socket, state);
|
|
3223
|
+
}
|
|
3224
|
+
});
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
function enqueueAgentBinaryFrame(socket, state, header, payload) {
|
|
3228
|
+
if (state.closed || socket.destroyed) {
|
|
3229
|
+
return;
|
|
3230
|
+
}
|
|
3231
|
+
if (!Array.isArray(state.binaryQueue)) {
|
|
3232
|
+
state.binaryQueue = [];
|
|
3233
|
+
}
|
|
3234
|
+
while (state.binaryQueue.length >= AGENT_BINARY_INGRESS_QUEUE_PACKETS) {
|
|
3235
|
+
dropQueuedAgentBinaryFrame(state);
|
|
3236
|
+
}
|
|
3237
|
+
state.binaryQueue.push({ header, payload });
|
|
3238
|
+
drainQueuedAgentBinaryFrames(socket, state);
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3181
3241
|
function handleAgentMessage(socket, state, message) {
|
|
3182
3242
|
if (!message || typeof message !== 'object') {
|
|
3183
3243
|
return;
|
|
@@ -3318,7 +3378,11 @@ export function createRemoteHub(options = {}) {
|
|
|
3318
3378
|
authenticated: false,
|
|
3319
3379
|
device: null,
|
|
3320
3380
|
inputOnly: false,
|
|
3321
|
-
frameOnly: false
|
|
3381
|
+
frameOnly: false,
|
|
3382
|
+
binaryQueue: [],
|
|
3383
|
+
binaryQueueDraining: false,
|
|
3384
|
+
binaryQueueDrops: 0,
|
|
3385
|
+
closed: false
|
|
3322
3386
|
};
|
|
3323
3387
|
|
|
3324
3388
|
const helloTimer = setTimeout(() => {
|
|
@@ -3359,7 +3423,7 @@ export function createRemoteHub(options = {}) {
|
|
|
3359
3423
|
return;
|
|
3360
3424
|
}
|
|
3361
3425
|
|
|
3362
|
-
|
|
3426
|
+
enqueueAgentBinaryFrame(socket, state, packet.header, packet.payload);
|
|
3363
3427
|
} catch (err) {
|
|
3364
3428
|
writeJsonLine(socket, { type: 'error', error: 'invalid-websocket-binary-frame' });
|
|
3365
3429
|
logWarn('remote', `invalid websocket binary frame: ${err?.message || err}`);
|
|
@@ -3367,6 +3431,8 @@ export function createRemoteHub(options = {}) {
|
|
|
3367
3431
|
};
|
|
3368
3432
|
|
|
3369
3433
|
const detach = reason => {
|
|
3434
|
+
state.closed = true;
|
|
3435
|
+
state.binaryQueue.length = 0;
|
|
3370
3436
|
allSockets.delete(socket);
|
|
3371
3437
|
clearTimeout(helloTimer);
|
|
3372
3438
|
detachInputSocket(socket, reason);
|
package/hub/src/server.js
CHANGED
|
@@ -21,9 +21,9 @@ const webIndexPath = resolve(webDistPath, 'index.html');
|
|
|
21
21
|
const packageInfo = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf8'));
|
|
22
22
|
const httpHost = process.env.LIVEDESK_HUB_HTTP_HOST || '0.0.0.0';
|
|
23
23
|
const httpPort = Number(process.env.LIVEDESK_HUB_HTTP_PORT || process.env.PORT || 5179);
|
|
24
|
-
const frameBackpressureBytes = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_BACKPRESSURE_BYTES',
|
|
25
|
-
const frameClientQueuePackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_QUEUE_PACKETS',
|
|
26
|
-
const frameClientDrainBudgetPackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_DRAIN_BUDGET_PACKETS',
|
|
24
|
+
const frameBackpressureBytes = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_BACKPRESSURE_BYTES', 16 * 1024 * 1024);
|
|
25
|
+
const frameClientQueuePackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_QUEUE_PACKETS', 12);
|
|
26
|
+
const frameClientDrainBudgetPackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_DRAIN_BUDGET_PACKETS', 96);
|
|
27
27
|
const frameClients = new Set();
|
|
28
28
|
const frameClientsByDeviceId = new Map();
|
|
29
29
|
const frameWildcardClients = new Set();
|
|
@@ -484,6 +484,8 @@ function buildRemoteFrameBinaryPacket(frameEvent) {
|
|
|
484
484
|
commandId: frame.commandId || '',
|
|
485
485
|
width: Number(frame.width || 0) || 0,
|
|
486
486
|
height: Number(frame.height || 0) || 0,
|
|
487
|
+
sourceWidth: Number(frame.sourceWidth || 0) || 0,
|
|
488
|
+
sourceHeight: Number(frame.sourceHeight || 0) || 0,
|
|
487
489
|
mimeType: frameEvent.mimeType || frame.mimeType || frame.format || 'image/jpeg',
|
|
488
490
|
mode: frame.mode || '',
|
|
489
491
|
frameMode: frame.frameMode || frame.mode || '',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livedesk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.119",
|
|
4
4
|
"description": "LiveDesk Hub and client launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"node": ">=20"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@livedesk/client": "0.1.
|
|
33
|
+
"@livedesk/client": "0.1.83",
|
|
34
34
|
"cors": "^2.8.5",
|
|
35
35
|
"express": "^4.21.2",
|
|
36
36
|
"ws": "^8.18.3"
|