Boosted speed of desktop multiplexor.
Ylian Saint-Hilaire committed
May 1, 2020 at 22:08 UTC
67f62cd00f5f1cc780c714f0509493fe7f08ad35
1 file changed
+53
-28
meshdesktopmultiplex.js
+53
-28
@@ -63,7 +63,7 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
63
obj.parent = parent;
64
obj.agent = null; // Reference to the connection object that is the agent.
65
obj.viewers = []; // Array of references to all viewers.
66
- obj.viewersSendingCount = 0; // Number of viewers currently activaly sending something.
66
+ obj.viewersOverflowCount = 0; // Number of viewers currently in overflow state.
67
obj.width = 0; // Current width of the display in pixels.
68
obj.height = 0; // Current height of the display in pixels.
69
obj.swidth = 0; // Current width of the display in tiles.
@@ -104,6 +104,7 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
104
peer.lastImageNumberSent = null;
105
peer.dataPtr = obj.firstData;
106
peer.sending = false;
107
+ peer.overflow = false;
108
peer.sendQueue = [];
109
peer.paused = false;
110
@@ -133,6 +134,7 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
134
// Setup the agent
135
obj.agent = peer;
136
peer.sending = false;
137
+ peer.overflow = false;
138
peer.sendQueue = [];
139
peer.paused = false;
140
@@ -172,6 +174,13 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
174
if (i == -1) return false;
175
obj.viewers.splice(i, 1);
176
177
+ // Resume flow control if this was the peer that was limiting traffic (because it was the fastest one).
178
+ if (peer.overflow == true) {
179
+ obj.viewersOverflowCount--;
180
+ peer.overflow = false;
181
+ if ((obj.viewersOverflowCount < obj.viewers.length) && (obj.recordingFileWriting == false) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
182
+ }
183
+
184
// Aggressive clean up of the viewer
185
delete peer.desktopPaused;
186
delete peer.imageCompression;
@@ -180,15 +189,9 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
189
delete peer.lastImageNumberSent;
190
delete peer.dataPtr;
191
delete peer.sending;
192
+ delete peer.overflow;
193
delete peer.sendQueue;
194
185
- // Resume flow control if this was the peer that was limiting traffic (because it was the fastest one).
186
- if (peer.sending == true) {
187
- obj.viewersSendingCount--;
188
- peer.sending = false;
189
- if ((obj.viewersSendingCount < obj.viewers.length) && (obj.recordingFileWriting == false) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
190
- }
191
-
195
// Log leaving the multiplex session
196
if (obj.startTime != null) {
197
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: peer.user._id, username: peer.user.name, msg: "Left the desktop multiplex session", protocol: 2 };
@@ -237,14 +240,17 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
240
//console.log('SendToAgent', data.length);
241
if (obj.agent.sending) {
242
obj.agent.sendQueue.push(data);
240
- } else {
241
- obj.agent.ws.send(data, sendAgentNext);
243
243
- // Flow control, pause all viewers
244
- for (var i in obj.viewers) {
245
- var v = obj.viewers[i];
246
- if (v.paused == false) { v.paused = true; v.ws._socket.pause(); }
244
+ // Flow control, pause all viewers is the queue is backing up
245
+ if (obj.agent.sendQueue > 10) {
246
+ obj.agent.overflow = true;
247
+ for (var i in obj.viewers) {
248
+ var v = obj.viewers[i];
249
+ if (v.paused == false) { v.paused = true; v.ws._socket.pause(); }
250
+ }
251
}
252
+ } else {
253
+ obj.agent.ws.send(data, sendAgentNext);
254
}
255
}
256
@@ -259,9 +265,12 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
265
obj.agent.sending = false;
266
267
// Flow control, resume all viewers
262
- for (var i in obj.viewers) {
263
- var v = obj.viewers[i];
264
- if (v.paused == true) { v.paused = false; v.ws._socket.resume(); }
268
+ if (obj.agent.overflow == true) {
269
+ obj.agent.overflow = false;
270
+ for (var i in obj.viewers) {
271
+ var v = obj.viewers[i];
272
+ if (v.paused == true) { v.paused = false; v.ws._socket.resume(); }
273
+ }
274
}
275
}
276
}
@@ -286,8 +295,27 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
295
}
296
297
// Flow control, pause the agent if needed
289
- obj.viewersSendingCount++;
290
- if ((obj.viewersSendingCount >= obj.viewers.length) && obj.agent && (obj.agent.paused == false)) { obj.agent.paused = true; obj.agent.ws._socket.pause(); }
298
+ checkViewerOverflow(viewer);
299
+ }
300
+ }
301
+
302
+ // Check if a viewer is in overflow situation
303
+ function checkViewerOverflow(viewer) {
304
+ if (viewer.overflow == true) return;
305
+ if ((viewer.sendQueue.length > 5) || ((viewer.dataPtr != null) && (viewer.dataPtr != obj.lastData))) {
306
+ viewer.overflow = true;
307
+ obj.viewersOverflowCount++;
308
+ if ((obj.viewersOverflowCount >= obj.viewers.length) && obj.agent && (obj.agent.paused == false)) { obj.agent.paused = true; obj.agent.ws._socket.pause(); }
309
+ }
310
+ }
311
+
312
+ // Check if a viewer is in underflow situation
313
+ function checkViewerUnderflow(viewer) {
314
+ if (viewer.overflow == false) return;
315
+ if ((viewer.sendQueue.length <= 5) && ((viewer.dataPtr == null) || (viewer.dataPtr == obj.lastData))) {
316
+ viewer.overflow = false;
317
+ obj.viewersOverflowCount--;
318
+ if ((obj.viewersOverflowCount < obj.viewers.length) && (obj.recordingFileWriting == false) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
319
}
320
}
321
@@ -296,12 +324,13 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
324
if (viewer.sendQueue == null) return;
325
if (viewer.sendQueue.length > 0) {
326
// Send from the pending send queue
299
- if (viewer.sending == false) { viewer.sending = true; obj.viewersSendingCount++; }
327
+ if (viewer.sending == false) { viewer.sending = true; }
328
if (viewer.slowRelay) {
329
setTimeout(function () { try { viewer.ws.send(viewer.sendQueue.shift(), function () { sendViewerNext(viewer); }); } catch (ex) { } }, viewer.slowRelay);
330
} else {
331
try { viewer.ws.send(viewer.sendQueue.shift(), function () { sendViewerNext(viewer); }); } catch (ex) { }
332
}
333
+ checkViewerOverflow(viewer);
334
} else {
335
if (viewer.dataPtr != null) {
336
// Send the next image
@@ -317,18 +346,14 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
346
}
347
348
// Flow control, pause the agent if needed
320
- if (viewer.sending == false) {
321
- viewer.sending = true;
322
- obj.viewersSendingCount++;
323
- if (((obj.viewersSendingCount >= obj.viewers.length) || (obj.recordingFileWriting == true)) && obj.agent && (obj.agent.paused == false)) { obj.agent.paused = true; obj.agent.ws._socket.pause(); }
324
- }
349
+ if (viewer.sending == false) { viewer.sending = true; }
350
+ checkViewerOverflow(viewer);
351
} else {
352
// Nothing to send
353
viewer.sending = false;
354
355
// Flow control, resume agent if needed
330
- obj.viewersSendingCount--;
331
- if ((obj.viewersSendingCount < obj.viewers.length) && (obj.recordingFileWriting == false) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
356
+ checkViewerUnderflow(viewer);
357
}
358
}
359
}
@@ -339,7 +364,7 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
364
obj.recordingFileWriting = true;
365
recordData(true, data, function () {
366
obj.recordingFileWriting = false;
342
- if ((obj.viewersSendingCount < obj.viewers.length) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
367
+ if ((obj.viewersOverflowCount < obj.viewers.length) && obj.agent && (obj.agent.paused == true)) { obj.agent.paused = false; obj.agent.ws._socket.resume(); }
368
obj.processAgentData(data);
369
});
370
} else {