From 64319741362d1e15620088442b507dfb04303ebf Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 11 May 2020 18:44:46 -0700 Subject: [PATCH] More device session notification work. --- agents/meshcore.js | 2 ++ meshagent.js | 18 ++++++++++++++++ meshdesktopmultiplex.js | 19 ++++++++++++++--- meshuser.js | 4 ++++ public/styles/style.css | 19 +++++++++++++++++ views/default.handlebars | 46 +++++++++++++++++++++++++++++++++------- 6 files changed, 97 insertions(+), 11 deletions(-) diff --git a/agents/meshcore.js b/agents/meshcore.js index 0077e145..7f66fd55 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1403,6 +1403,7 @@ function createMeshCore(agent) { if (this.httprequest.desktop.kvm.tunnels != null) { 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) { } } 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) { } } + try { mesh.SendCommand({ action: 'sessions', type: 'kvm', value: users }); } catch (ex) { } } this.end = function () { @@ -1417,6 +1418,7 @@ function createMeshCore(agent) { if (this.httprequest.desktop.kvm.tunnels != null) { 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) { } } 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) { } } + try { mesh.SendCommand({ action: 'sessions', type: 'kvm', value: users }); } catch (ex) { } } // Unpipe the web socket diff --git a/meshagent.js b/meshagent.js index edb2d34b..a0bc98e7 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1327,6 +1327,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { }); break; } + case 'sessions': { + // This is a list of sessions provided by the agent + if (obj.sessions == null) { obj.sessions = {}; } + if (command.type == 'kvm') { obj.sessions.kvm = command.value; } + obj.updateSessions(); + break; + } case 'plugin': { if ((parent.parent.pluginHandler == null) || (typeof command.plugin != 'string')) break; try { @@ -1350,6 +1357,17 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } } + // Notify update of sessions + obj.updateSessions = function () { + // Perform some clean up + for (var i in obj.sessions) { if (Object.keys(obj.sessions[i]).length == 0) { delete obj.sessions[i]; } } + if (Object.keys(obj.sessions).length == 0) { delete obj.sessions; } + + // Event the new sessions, this will notify everyone that agent sessions have changed + var event = { etype: 'node', action: 'devicesessions', nodeid: obj.dbNodeKey, domain: domain.id, sessions: obj.sessions, nolog: 1 }; + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event); + } + // Change the current core information string and event it function ChangeAgentCoreInfo(command) { if (obj.agentInfo.capabilities & 0x40) return; diff --git a/meshdesktopmultiplex.js b/meshdesktopmultiplex.js index b4b3b6e2..fa5f0f8b 100644 --- a/meshdesktopmultiplex.js +++ b/meshdesktopmultiplex.js @@ -260,6 +260,9 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) { obj.startTime = null; } + // Send an updated list of all peers to all viewers + obj.sendSessionMetadata(); + parent.parent.debug('relay', 'DesktopRelay: Disposing desktop multiplexor'); } @@ -307,10 +310,20 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) { // Send the list of all users currently vieweing this session to all viewers and servers obj.sendSessionMetadata = function () { var allUsers = {}; - 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]++; } } } - obj.sendToAllViewers(JSON.stringify({ type: 'metadata', 'ctrlChannel': '102938', users: allUsers, startTime: obj.startTime })); + if (obj.viewers != null) { + 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]++; } } } + obj.sendToAllViewers(JSON.stringify({ type: 'metadata', 'ctrlChannel': '102938', users: allUsers, startTime: obj.startTime })); + } - // TODO: Update the servers + // Update the sessions attached the to agent + if (obj.nodeid != null) { + const xagent = parent.wsagents[obj.nodeid]; + if (xagent != null) { + if (xagent.sessions == null) { xagent.sessions = {}; } + xagent.sessions.multidesk = allUsers; + xagent.updateSessions(); + } + } } // Send this command to all viewers diff --git a/meshuser.js b/meshuser.js index 0d914a5d..b838425c 100644 --- a/meshuser.js +++ b/meshuser.js @@ -586,6 +586,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (docs[i].userloc != null) { delete docs[i].userloc; } } + // Add device sessions + const xagent = parent.wsagents[docs[i]._id]; + if ((xagent != null) && (xagent.sessions != null)) { docs[i].sessions = xagent.sessions; } + r[meshid].push(docs[i]); } try { ws.send(JSON.stringify({ action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag })); } catch (ex) { } diff --git a/public/styles/style.css b/public/styles/style.css index 0ab7839e..e3bbe687 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -784,6 +784,25 @@ NoMeshesPanel img { background-color:#44F; } +.deviceNotifyLargeDot { + text-align:center; + position:absolute; + right:10px; + top:140px; + width:40px; + height:40px; + color:#FFF; + padding:2px; + background-color:#00F; + border-radius:20px; + box-shadow: 2px 2px 10px black; + cursor:pointer; +} + + .deviceNotifyLargeDot:hover { + background-color:#44F; + } + #xdevices { max-height: calc(100vh - 242px); overflow-y: auto; diff --git a/views/default.handlebars b/views/default.handlebars index 5ac1fed3..c954afcf 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -485,7 +485,8 @@
- + +
@@ -2720,6 +2721,23 @@ } break; } + case 'devicesessions': { + // List of sessions for a given device + var node = getNodeFromId(message.event.nodeid); + if (node == null) break; // Unknown node + node.sessions = message.event.sessions; + if (node.sessions != null) { + for (var i in node.sessions) { if (Object.keys(node.sessions[i]).length == 0) { delete node.sessions[i]; } } + if (Object.keys(node.sessions).length == 0) { delete node.sessions; } + } + masterUpdate(4); + if ((currentNode != null) && (currentNode._id == message.event.nodeid)) { gotoDevice(currentNode._id, xxcurrentView, true); } + + // If we are looking at the sessions dialog box for this device now, update it + if (xxdialogTag == ('SESSIONS-' + message.event.nodeid)) { showDeviceSessions(message.event.nodeid, true); } + + break; + } case 'stopped': { // Server is stopping. // Disconnect //console.log(message.msg); @@ -3404,13 +3422,21 @@ } // Show currently active sessions on this device - function showDeviceSessions(nodeid) { - if (xxdialogMode) return; - var node = getNodeFromId(nodeid), x = ''; - if (node == null) return; - console.log(node.sessions); - x += addHtmlValue4("User", '1 session'); // TODO - setDialogMode(2, "Sessions - " + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + nodeid); + function showDeviceSessions(nodeid, force) { + if (xxdialogMode && !force) return; + var node = null, x = ''; + if (nodeid == null) { node = currentNode; } else { node = getNodeFromId(nodeid); } + if ((node == null) || (node.sessions == null)) { setDialogMode(0); return; } + for (var i in node.sessions) { + if ((i == 'kvm') && (node.sessions.multidesk == null)) { + x += '' + "Remote Desktop" + ''; + 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]))); } + } else if (i == 'multidesk') { + x += '' + "Remote Desktop" + ''; + 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])))); } + } + } + if (x != '') setDialogMode(2, "Sessions - " + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + node._id); } function toggleCollapseGroup(id, id2, type) { @@ -4950,6 +4976,9 @@ if (!currentNode || currentNode._id != node._id || refresh == true) { currentNode = node; + // Device Notification + QV('p10deviceNotify', currentNode.sessions != null); + // Add node name var nname = EscapeHtml(node.name), nnameEx; if (nname.length == 0) { nname = '' + "None" + ''; } @@ -12426,6 +12455,7 @@ function nobreak(x) { return x.split(' ').join(' '); } function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); } function encodeURIComponentEx(txt) { return encodeURIComponent(txt).replace(/'/g,'%27'); }; + function getUserName(userid) { if (users && users[userid] != null) return users[userid].name; return userid.split('/')[2]; }