Added remote desktop metadata support.

This commit is contained in:
Ylian Saint-Hilaire 2020-05-06 23:23:27 -07:00
parent b96ababf0b
commit 139a5ad174
9 changed files with 1198 additions and 1099 deletions

View File

@ -228,8 +228,7 @@ function createMeshCore(agent) {
if (cert.tls) { ddb.Put('SelfNodeTlsCert', cert.tls.pfx); }
if (proxyConfig) {
ddb.Put('WebProxy', proxyConfig.host + ':' + proxyConfig.port);
}
else {
} else {
ddb.Put('ignoreProxyFile', '1');
}
@ -1395,18 +1394,34 @@ function createMeshCore(agent) {
this.httprequest.desktop.kvm.parent = this.httprequest.desktop;
this.desktop = this.httprequest.desktop;
// Add ourself to the list of remote desktop sessions
if (this.httprequest.desktop.kvm.tunnels == null) { this.httprequest.desktop.kvm.tunnels = []; }
this.httprequest.desktop.kvm.tunnels.push(this);
// Send a metadata update to all desktop sessions
var users = {};
for (var i in this.httprequest.desktop.kvm.tunnels) { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } }
for (var i in this.httprequest.desktop.kvm.tunnels) { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); }
this.end = function () {
--this.desktop.kvm.connectionCount;
// Remove ourself from the list of remote desktop session
var i = this.desktop.kvm.tunnels.indexOf(this);
if (i >= 0) { this.desktop.kvm.tunnels.splice(i, 1); }
// Send a metadata update to all desktop sessions
var users = {};
for (var i in this.httprequest.desktop.kvm.tunnels) { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } }
for (var i in this.httprequest.desktop.kvm.tunnels) { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); }
// Unpipe the web socket
try
{
this.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this);
}
catch(xx)
{
}
catch(ex) { }
// Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
if (this.rtcchannel)
@ -1416,9 +1431,7 @@ function createMeshCore(agent) {
this.rtcchannel.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this.rtcchannel);
}
catch(xx)
{
}
catch(ex) { }
}
// Place wallpaper back if needed
@ -1434,8 +1447,7 @@ function createMeshCore(agent) {
this.httprequest.desktop.kvm.connectionBar.close();
this.httprequest.desktop.kvm.connectionBar = null;
}
}
else {
} else {
for (var i in this.httprequest.desktop.kvm.users) {
if (this.httprequest.desktop.kvm.users[i] == this.httprequest.username && this.httprequest.desktop.kvm.connectionBar) {
this.httprequest.desktop.kvm.users.splice(i, 1);

View File

@ -132,6 +132,9 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: peer.user._id, username: peer.user.name, msg: "Joined desktop multiplex session", protocol: 2 };
parent.parent.DispatchEvent(['*', obj.nodeid, peer.user._id, obj.meshid], obj, event);
}
// Send an updated list of all peers to all viewers
obj.sendSessionMetadata();
} else {
//console.log('addPeer-agent', obj.nodeid);
if (obj.agent != null) return false;
@ -169,15 +172,17 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
obj.agent = null;
// Agent has disconnected, disconnect everyone.
for (var i in obj.viewers) { obj.viewers[i].close(); }
if (obj.viewers != null) { for (var i in obj.viewers) { obj.viewers[i].close(); } }
dispose();
return true;
} else {
//console.log('removePeer-viewer', obj.nodeid);
// Remove a viewer
if (obj.viewers != null) {
var i = obj.viewers.indexOf(peer);
if (i == -1) return false;
obj.viewers.splice(i, 1);
}
// Resume flow control if this was the peer that was limiting traffic (because it was the fastest one).
if (peer.overflow == true) {
@ -205,6 +210,9 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
// If this is the last viewer, disconnect the agent
if ((obj.viewers.length == 0) && (obj.agent != null)) { obj.agent.close(); dispose(); return true; }
// Send an updated list of all peers to all viewers
obj.sendSessionMetadata();
}
return false;
}
@ -294,6 +302,13 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
}
}
// Send the list of all users currently vieweing this session to all viewers
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 }));
}
// Send this command to all viewers
obj.sendToAllViewers = function (data) {
for (var i in obj.viewers) { obj.sendToViewer(obj.viewers[i], data); }

View File

@ -431,7 +431,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
switch (command.action) {
case 'pong': { break; } // NOP
case 'ping': { try { ws.send(JSON.stringify({ action: 'pong' })); } catch (ex) { } break; }
case 'ping': { try { ws.send('{action:"pong"}'); } catch (ex) { } break; }
case 'intersession':
{
// Sends data between sessions of the same user

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.5.24",
"version": "0.5.25",
"keywords": [
"Remote Management",
"Intel AMT",

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
obj.meshserver = meshserver;
obj.authCookie = authCookie;
obj.rauthCookie = rauthCookie;
obj.State = 0;
obj.State = 0; // 0 = Disconnected, 1 = Connected, 2 = Connected to server, 3 = End-to-end connection.
obj.nodeid = null;
obj.options = null;
obj.socket = null;
@ -35,6 +35,10 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
obj.consoleMessage = null;
obj.onConsoleMessageChange = null;
// Session Metadata
obj.metadata = null;
obj.onMetadataChange = null;
// Private method
//obj.debug = function (msg) { console.log(msg); }
@ -74,6 +78,9 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
if ((typeof args != 'undefined') && args.redirtrace) { console.log('RedirRecv', controlMsg); }
if (controlMsg.type == 'console') {
obj.setConsoleMessage(controlMsg.msg, controlMsg.msgid, controlMsg.msgargs, controlMsg.timeout);
} else if (controlMsg.type == 'metadata') {
obj.metadata = controlMsg;
if (obj.onMetadataChange) obj.onMetadataChange(obj.metadata);
} else if ((controlMsg.type == 'rtt') && (typeof controlMsg.time == 'number')) {
obj.latency.current = (new Date().getTime()) - controlMsg.time;
if (obj.latency.callbacks != null) { obj.latency.callback(obj.latency.current); }

View File

@ -1 +1 @@
var MeshServerCreateControl=function(t,e){var o={State:0,connectstate:0,pingTimer:null};return o.authCookie=e,o.trace=!1,o.xxStateChange=function(e,t){if(o.State!=e){var n=o.State;o.State=e,o.onStateChanged&&o.onStateChanged(o,o.State,n,t)}},o.Start=function(){if(0==o.connectstate){o.connectstate=0;var e=window.location.protocol.replace("http","ws")+"//"+window.location.host+t+"control.ashx";o.authCookie&&""!=o.authCookie&&(e+="?auth="+o.authCookie),o.socket=new WebSocket(e),o.socket.onopen=function(e){o.connectstate=1},o.socket.onmessage=o.xxOnMessage,o.socket.onclose=function(e){o.Stop(e.code)},o.xxStateChange(1,0),null!=o.pingTimer&&clearInterval(o.pingTimer),o.pingTimer=setInterval(function(){o.send({action:"ping"})},29e3)}},o.Stop=function(e){o.connectstate=0,o.socket&&(o.socket.close(),delete o.socket),null!=o.pingTimer&&(clearInterval(o.pingTimer),o.pingTimer=null),o.xxStateChange(0,e)},o.xxOnMessage=function(e){var t;1==o.State&&o.xxStateChange(2);try{t=JSON.parse(e.data)}catch(e){return}if("object"==typeof t&&"pong"!=t.action){if("close"==t.action)return t.msg&&console.log(t.msg),void o.Stop(t.cause);o.trace&&console.log("RECV",t),o.onMessage&&o.onMessage(o,t)}},o.send=function(e){null!=o.socket&&1==o.connectstate&&(o.trace&&"ping"!=e.action&&console.log("SEND",e),o.socket.send(JSON.stringify(e)))},o}
var MeshServerCreateControl=function(e,t){var o={State:0,connectstate:0,pingTimer:null};return o.authCookie=t,o.trace=!1,o.xxStateChange=function(t,e){if(o.State!=t){var n=o.State;o.State=t,o.onStateChanged&&o.onStateChanged(o,o.State,n,e)}},o.Start=function(){if(0==o.connectstate){o.connectstate=0;var t=window.location.protocol.replace("http","ws")+"//"+window.location.host+e+"control.ashx";o.authCookie&&""!=o.authCookie&&(t+="?auth="+o.authCookie),o.socket=new WebSocket(t),o.socket.onopen=function(t){o.connectstate=1},o.socket.onmessage=o.xxOnMessage,o.socket.onclose=function(t){o.Stop(t.code)},o.xxStateChange(1,0),null!=o.pingTimer&&clearInterval(o.pingTimer),o.pingTimer=setInterval(function(){o.send({action:"ping"})},29e3)}},o.Stop=function(t){o.connectstate=0,o.socket&&(o.socket.close(),delete o.socket),null!=o.pingTimer&&(clearInterval(o.pingTimer),o.pingTimer=null),o.xxStateChange(0,t)},o.xxOnMessage=function(t){var e;1==o.State&&o.xxStateChange(2);try{e=JSON.parse(t.data)}catch(t){return}if("object"==typeof e&&"pong"!=e.action){if("ping"==e.action&&o.send({action:"pong"}),"close"==e.action)return e.msg&&console.log(e.msg),void o.Stop(e.cause);o.trace&&console.log("RECV",e),o.onMessage&&o.onMessage(o,e)}},o.send=function(t){null!=o.socket&&1==o.connectstate&&(o.trace&&"ping"!=t.action&&console.log("SEND",t),o.socket.send(JSON.stringify(t)))},o}

File diff suppressed because it is too large Load Diff

View File

@ -530,7 +530,7 @@
<span id=connectbutton1span><input type=button id=connectbutton1 cmenu="deskConnectButton" value="Connect" onclick=connectDesktop(event,3) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
<span id=connectbutton1hspan>&nbsp;<input type=button id=connectbutton1h value="HW Connect" title="Connect using Intel AMT hardware KVM" onclick=connectDesktop(event,2) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
<span id=disconnectbutton1span>&nbsp;<input type=button id=disconnectbutton1 value="Disconnect" onclick=connectDesktop(event,0) onkeypress="return false" onkeydown="return false" /></span>
&nbsp;<span id="deskstatus">Disconnected</span>
&nbsp;<span id="deskstatus">Disconnected</span><span id="deskmetadata"></span>
</div>
</div>
<div id=deskarea2 style="">
@ -5803,6 +5803,7 @@
desktop = xdesk;
if (desktop.m.SendCompressionLevel) { desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); }
desktop.onStateChanged = onDesktopStateChange;
desktop.onMetadataChange = function(metadata) { updateMetadata(desktop, 'deskmetadata'); }
desktopNode = currentNode;
onDesktopStateChange(desktop, desktop.State);
delete multiDesktop[currentNode._id];
@ -5818,6 +5819,7 @@
desktopNode = currentNode;
updateDesktopButtons();
deskAdjust();
updateMetadata(desktop, 'deskmetadata');
}
// Show and enable the right buttons
@ -6005,6 +6007,7 @@
p11clearConsoleMsg();
}
}
desktop.onMetadataChange = function(metadata) { updateMetadata(desktop, 'deskmetadata'); }
desktop.m.CompressionLevel = desktopsettings.quality; // Number from 1 to 100. 50 or less is best.
desktop.m.ScalingLevel = desktopsettings.scaling;
if (desktopsettings.framerate) { desktop.m.FrameRateTimer = desktopsettings.framerate; }
@ -6026,6 +6029,36 @@
}
}
function updateMetadata(conn, elementid) {
var str = '', viewerCount = 0;
if (conn && (conn.State == 3)) {
if (conn.metadata && conn.metadata.users) { for (var i in conn.metadata.users) { viewerCount++; } }
if (viewerCount > 1) { str = '<span onclick=showSessionMetadata(1) style=cursor:pointer>' + format(", {0} watching", viewerCount) + '</span>'; }
}
QH('deskmetadata', str);
if ((conn == desktop) && (xxdialogTag == ('sessionMetadata1'))) { showSessionMetadata(1); }
}
function showSessionMetadata(cid) {
if (xxdialogMode && (xxdialogTag != ('sessionMetadata' + cid))) return;
if (xxdialogMode) { setDialogMode(0); }
var conn = null;
if (cid == 1) { conn = desktop; }
if (conn && conn.metadata) {
var x = '';
if (conn.metadata.startTime) { x += addHtmlValue4("Start Time", printDateTime(new Date(conn.metadata.startTime))); }
if (conn.metadata.users) {
for (var i in conn.metadata.users) {
var val = (conn.metadata.users[i] == 1)?"1 connection":format("{0} connections", conn.metadata.users[i]);
var username = i.split('/')[2];
if ((users != null) && (users[i] != null)) { username = users[i].name; }
x += addHtmlValue4(format("User \"{0}\"", username), val);
}
}
setDialogMode(2, "Session Information", 1, null, x, 'sessionMetadata' + cid);
}
}
function p11clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); QV('p11DeskConsoleMsg', false); if (p11DeskConsoleMsgTimer) { clearTimeout(p11DeskConsoleMsgTimer); p11DeskConsoleMsgTimer = null; } }
function p12clearConsoleMsg() { QH('p12TermConsoleMsg', ''); QV('p12TermConsoleMsg', false); if (p12TermConsoleMsgTimer) { clearTimeout(p12TermConsoleMsgTimer); p12TermConsoleMsgTimer = null; } }
function p13clearConsoleMsg() { QH('p13FilesConsoleMsg', ''); QV('p13FilesConsoleMsg', false); if (p13FilesConsoleMsgTimer) { clearTimeout(p13FilesConsoleMsgTimer); p13FilesConsoleMsgTimer = null; } }
@ -6090,6 +6123,7 @@
updateDesktopButtons();
deskAdjust();
setTimeout(deskAdjust, 50);
updateMetadata(desktop, 'deskmetadata');
}
function updateSessionTime() {