More device session notification work.

Ylian Saint-Hilaire committed May 11, 2020 at 18:44 UTC 64319741362d1e15620088442b507dfb04303ebf
6 files changed +97 -11
agents/meshcore.js
+2
@@ -1403,6 +1403,7 @@ function createMeshCore(agent) {
1403 if (this.httprequest.desktop.kvm.tunnels != null) {
1404 for (var i in this.httprequest.desktop.kvm.tunnels) { try { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } } catch (ex) { } }
1405 for (var i in this.httprequest.desktop.kvm.tunnels) { try { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); } catch (ex) { } }
1406 + try { mesh.SendCommand({ action: 'sessions', type: 'kvm', value: users }); } catch (ex) { }
1407 }
1408
1409 this.end = function () {
@@ -1417,6 +1418,7 @@ function createMeshCore(agent) {
1418 if (this.httprequest.desktop.kvm.tunnels != null) {
1419 for (var i in this.httprequest.desktop.kvm.tunnels) { try { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } } catch (ex) { } }
1420 for (var i in this.httprequest.desktop.kvm.tunnels) { try { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); } catch (ex) { } }
1421 + try { mesh.SendCommand({ action: 'sessions', type: 'kvm', value: users }); } catch (ex) { }
1422 }
1423
1424 // Unpipe the web socket
meshagent.js
+18
@@ -1327,6 +1327,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1327 });
1328 break;
1329 }
1330 + case 'sessions': {
1331 + // This is a list of sessions provided by the agent
1332 + if (obj.sessions == null) { obj.sessions = {}; }
1333 + if (command.type == 'kvm') { obj.sessions.kvm = command.value; }
1334 + obj.updateSessions();
1335 + break;
1336 + }
1337 case 'plugin': {
1338 if ((parent.parent.pluginHandler == null) || (typeof command.plugin != 'string')) break;
1339 try {
@@ -1350,6 +1357,17 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1357 }
1358 }
1359
1360 + // Notify update of sessions
1361 + obj.updateSessions = function () {
1362 + // Perform some clean up
1363 + for (var i in obj.sessions) { if (Object.keys(obj.sessions[i]).length == 0) { delete obj.sessions[i]; } }
1364 + if (Object.keys(obj.sessions).length == 0) { delete obj.sessions; }
1365 +
1366 + // Event the new sessions, this will notify everyone that agent sessions have changed
1367 + var event = { etype: 'node', action: 'devicesessions', nodeid: obj.dbNodeKey, domain: domain.id, sessions: obj.sessions, nolog: 1 };
1368 + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
1369 + }
1370 +
1371 // Change the current core information string and event it
1372 function ChangeAgentCoreInfo(command) {
1373 if (obj.agentInfo.capabilities & 0x40) return;
meshdesktopmultiplex.js
+16 -3
@@ -260,6 +260,9 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
260 obj.startTime = null;
261 }
262
263 + // Send an updated list of all peers to all viewers
264 + obj.sendSessionMetadata();
265 +
266 parent.parent.debug('relay', 'DesktopRelay: Disposing desktop multiplexor');
267 }
268
@@ -307,10 +310,20 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
310 // Send the list of all users currently vieweing this session to all viewers and servers
311 obj.sendSessionMetadata = function () {
312 var allUsers = {};
310 - for (var i in obj.viewers) { var v = obj.viewers[i]; if ((v.user != null) && (v.user._id != null)) { if (allUsers[v.user._id] == null) { allUsers[v.user._id] = 1; } else { allUsers[v.user._id]++; } } }
311 - obj.sendToAllViewers(JSON.stringify({ type: 'metadata', 'ctrlChannel': '102938', users: allUsers, startTime: obj.startTime }));
313 + if (obj.viewers != null) {
314 + for (var i in obj.viewers) { var v = obj.viewers[i]; if ((v.user != null) && (v.user._id != null)) { if (allUsers[v.user._id] == null) { allUsers[v.user._id] = 1; } else { allUsers[v.user._id]++; } } }
315 + obj.sendToAllViewers(JSON.stringify({ type: 'metadata', 'ctrlChannel': '102938', users: allUsers, startTime: obj.startTime }));
316 + }
317
313 - // TODO: Update the servers
318 + // Update the sessions attached the to agent
319 + if (obj.nodeid != null) {
320 + const xagent = parent.wsagents[obj.nodeid];
321 + if (xagent != null) {
322 + if (xagent.sessions == null) { xagent.sessions = {}; }
323 + xagent.sessions.multidesk = allUsers;
324 + xagent.updateSessions();
325 + }
326 + }
327 }
328
329 // Send this command to all viewers
meshuser.js
+4
@@ -586,6 +586,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
586 if (docs[i].userloc != null) { delete docs[i].userloc; }
587 }
588
589 + // Add device sessions
590 + const xagent = parent.wsagents[docs[i]._id];
591 + if ((xagent != null) && (xagent.sessions != null)) { docs[i].sessions = xagent.sessions; }
592 +
593 r[meshid].push(docs[i]);
594 }
595 try { ws.send(JSON.stringify({ action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag })); } catch (ex) { }
public/styles/style.css
+19
@@ -784,6 +784,25 @@ NoMeshesPanel img {
784 background-color:#44F;
785 }
786
787 +.deviceNotifyLargeDot {
788 + text-align:center;
789 + position:absolute;
790 + right:10px;
791 + top:140px;
792 + width:40px;
793 + height:40px;
794 + color:#FFF;
795 + padding:2px;
796 + background-color:#00F;
797 + border-radius:20px;
798 + box-shadow: 2px 2px 10px black;
799 + cursor:pointer;
800 +}
801 +
802 + .deviceNotifyLargeDot:hover {
803 + background-color:#44F;
804 + }
805 +
806 #xdevices {
807 max-height: calc(100vh - 242px);
808 overflow-y: auto;
views/default.handlebars
+38 -8
@@ -485,7 +485,8 @@
485 <div id=p10html></div>
486 </td>
487 <td style=width:20px></td>
488 - <td style=width:200px;vertical-align:top valign=top>
488 + <td style=width:200px;vertical-align:top;position:relative valign=top>
489 + <img id="p10deviceNotify" onclick=showDeviceSessions() class=deviceNotifyLargeDot src=images/icon-relay-notify.png width=16 height=16>
490 <a href=# onclick=p10showiconselector()><img id=MainComputerImage></a>
491 <div id=MainComputerState></div>
492 </td>
@@ -2720,6 +2721,23 @@
2721 }
2722 break;
2723 }
2724 + case 'devicesessions': {
2725 + // List of sessions for a given device
2726 + var node = getNodeFromId(message.event.nodeid);
2727 + if (node == null) break; // Unknown node
2728 + node.sessions = message.event.sessions;
2729 + if (node.sessions != null) {
2730 + for (var i in node.sessions) { if (Object.keys(node.sessions[i]).length == 0) { delete node.sessions[i]; } }
2731 + if (Object.keys(node.sessions).length == 0) { delete node.sessions; }
2732 + }
2733 + masterUpdate(4);
2734 + if ((currentNode != null) && (currentNode._id == message.event.nodeid)) { gotoDevice(currentNode._id, xxcurrentView, true); }
2735 +
2736 + // If we are looking at the sessions dialog box for this device now, update it
2737 + if (xxdialogTag == ('SESSIONS-' + message.event.nodeid)) { showDeviceSessions(message.event.nodeid, true); }
2738 +
2739 + break;
2740 + }
2741 case 'stopped': { // Server is stopping.
2742 // Disconnect
2743 //console.log(message.msg);
@@ -3404,13 +3422,21 @@
3422 }
3423
3424 // Show currently active sessions on this device
3407 - function showDeviceSessions(nodeid) {
3408 - if (xxdialogMode) return;
3409 - var node = getNodeFromId(nodeid), x = '';
3410 - if (node == null) return;
3411 - console.log(node.sessions);
3412 - x += addHtmlValue4("User", '1 session'); // TODO
3413 - setDialogMode(2, "Sessions - " + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + nodeid);
3425 + function showDeviceSessions(nodeid, force) {
3426 + if (xxdialogMode && !force) return;
3427 + var node = null, x = '';
3428 + if (nodeid == null) { node = currentNode; } else { node = getNodeFromId(nodeid); }
3429 + if ((node == null) || (node.sessions == null)) { setDialogMode(0); return; }
3430 + for (var i in node.sessions) {
3431 + if ((i == 'kvm') && (node.sessions.multidesk == null)) {
3432 + x += '<u>' + "Remote Desktop" + '</u>';
3433 + for (var j in node.sessions.kvm) { x += addHtmlValue4(getUserName(j), (node.sessions.kvm[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.kvm[j]))); }
3434 + } else if (i == 'multidesk') {
3435 + x += '<u>' + "Remote Desktop" + '</u>';
3436 + for (var j in node.sessions.multidesk) { x += addHtmlValue4(getUserName(j), ((node.sessions.multidesk[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.multidesk[j])))); }
3437 + }
3438 + }
3439 + if (x != '') setDialogMode(2, "Sessions - " + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + node._id);
3440 }
3441
3442 function toggleCollapseGroup(id, id2, type) {
@@ -4950,6 +4976,9 @@
4976 if (!currentNode || currentNode._id != node._id || refresh == true) {
4977 currentNode = node;
4978
4979 + // Device Notification
4980 + QV('p10deviceNotify', currentNode.sessions != null);
4981 +
4982 // Add node name
4983 var nname = EscapeHtml(node.name), nnameEx;
4984 if (nname.length == 0) { nname = '<i>' + "None" + '</i>'; }
@@ -12426,6 +12455,7 @@
12455 function nobreak(x) { return x.split(' ').join('&nbsp;'); }
12456 function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
12457 function encodeURIComponentEx(txt) { return encodeURIComponent(txt).replace(/'/g,'%27'); };
12458 + function getUserName(userid) { if (users && users[userid] != null) return users[userid].name; return userid.split('/')[2]; }
12459
12460 </script>
12461 </body>