KASM-3102 Allow setting the idle timeout (#41)

refactor idle timeout to use date diff
This commit is contained in:
Matt McClaskey 2022-11-11 09:29:52 -05:00 committed by GitHub
parent c5350ba2d7
commit 3a6a63cde3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 56 deletions

View File

@ -46,9 +46,6 @@ import * as WebUtil from "./webutil.js";
const PAGE_TITLE = "KasmVNC";
var delta = 500;
var lastKeypressTime = 0;
var lastKeypressCode = -1;
var currentEventCount = -1;
var idleCounter = 0;
@ -1423,46 +1420,41 @@ const UI = {
/****
* Kasm VDI specific
*****/
if (WebUtil.isInsideKasmVDI())
{
if (window.addEventListener) { // Mozilla, Netscape, Firefox
//window.addEventListener('load', WindowLoad, false);
window.addEventListener('message', UI.receiveMessage, false);
} else if (window.attachEvent) { //IE
window.attachEvent('onload', WindowLoad);
window.attachEvent('message', UI.receiveMessage);
}
if (UI.rfb.clipboardDown){
UI.rfb.addEventListener("clipboard", UI.clipboardRx);
}
UI.rfb.addEventListener("disconnect", UI.disconnectedRx);
document.getElementById('noVNC_control_bar_anchor').setAttribute('style', 'display: none');
//keep alive for websocket connection to stay open, since we may not control reverse proxies
//send a keep alive within a window that we control
setInterval(function() {
if (currentEventCount!=UI.rfb.sentEventsCounter) {
idleCounter=0;
currentEventCount=UI.rfb.sentEventsCounter;
} else {
idleCounter+=1;
var idleDisconnect = parseFloat(UI.rfb.idleDisconnect);
if ((idleCounter / 2) >= idleDisconnect) {
//idle for longer than the limit, disconnect
currentEventCount = -1;
idleCounter = 0;
parent.postMessage({ action: 'idle_session_timeout', value: 'Idle session timeout exceeded'}, '*' );
//UI.rfb.disconnect();
} else {
//send a keep alive
UI.rfb.sendKey(1, null, false);
currentEventCount=UI.rfb.sentEventsCounter;
}
}
}, 30000);
} else {
if (WebUtil.isInsideKasmVDI()) {
if (window.addEventListener) { // Mozilla, Netscape, Firefox
//window.addEventListener('load', WindowLoad, false);
window.addEventListener('message', UI.receiveMessage, false);
} else if (window.attachEvent) { //IE
window.attachEvent('onload', WindowLoad);
window.attachEvent('message', UI.receiveMessage);
}
if (UI.rfb.clipboardDown){
UI.rfb.addEventListener("clipboard", UI.clipboardRx);
}
UI.rfb.addEventListener("disconnect", UI.disconnectedRx);
document.getElementById('noVNC_control_bar_anchor').setAttribute('style', 'display: none');
//keep alive for websocket connection to stay open, since we may not control reverse proxies
//send a keep alive within a window that we control
UI._sessionTimeoutInterval = setInterval(function() {
const timeSinceLastActivityInS = (Date.now() - UI.rfb.lastActiveAt) / 1000;
let idleDisconnectInS = 1200; //20 minute default
if (Number.isFinite(UI.rfb.idleDisconnect)) {
idleDisconnectInS = parseFloat(UI.rfb.idleDisconnect) * 60;
}
console.log("Current idle time " + timeSinceLastActivityInS + " max value is " + idleDisconnectInS);
if (timeSinceLastActivityInS > idleDisconnectInS) {
parent.postMessage({ action: 'idle_session_timeout', value: 'Idle session timeout exceeded'}, '*' );
} else {
//send keep-alive
UI.rfb.sendKey(1, null, false);
}
}, 5000);
} else {
document.getElementById('noVNC_status').style.visibility = "visible";
}
}
//key events for KasmVNC control
document.addEventListener('keyup', function (event) {
@ -1493,7 +1485,7 @@ const UI = {
UI.updateVisualState('disconnecting');
// Don't display the connection settings until we're actually disconnected
clearInterval(UI._sessionTimeoutInterval);
},
reconnect() {
@ -1680,6 +1672,14 @@ const UI = {
UI.toggleWebRTC();
}
break;
case 'set_idle_timeout':
//message value in seconds
const idle_timeout_min = Math.ceil(event.data.value / 60);
UI.forceSetting('idle_disconnect', idle_timeout_min, false);
UI.rfb.idleDisconnect = idle_timeout_min;
console.log(`Updated the idle timeout to ${event.data.value}s`);
break;
}
}
},

View File

@ -340,7 +340,7 @@ export default class RFB extends EventTargetMixin {
this.dragViewport = false;
this.focusOnClick = true;
this.sentEventsCounter = 0;
this.lastActiveAt = Date.now();
this._viewOnly = false;
this._clipViewport = false;
@ -813,8 +813,10 @@ export default class RFB extends EventTargetMixin {
sendKey(keysym, code, down) {
if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; }
this.sentEventsCounter+=1;
if (code !== null) {
this._setLastActive();
}
if (down === undefined) {
this.sendKey(keysym, code, true);
this.sendKey(keysym, code, false);
@ -872,8 +874,6 @@ export default class RFB extends EventTargetMixin {
if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; }
if (!(typeof text === 'string' && text.length > 0)) { return; }
this.sentEventsCounter+=1;
let data = new TextEncoder().encode(text);
let h = hashUInt8Array(data);
@ -894,7 +894,6 @@ export default class RFB extends EventTargetMixin {
async clipboardPasteDataFrom(clipdata) {
if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; }
this.sentEventsCounter+=1;
let dataset = [];
let mimes = [];
@ -965,6 +964,10 @@ export default class RFB extends EventTargetMixin {
// ===== PRIVATE METHODS =====
_setLastActive() {
this.lastActiveAt = Date.now();
}
_changeTransitConnectionState(value) {
Log.Info("Transit state change from " + this._transitConnectionState.toString() + ' to ' + value.toString());
this._transitConnectionState = value;
@ -977,7 +980,7 @@ export default class RFB extends EventTargetMixin {
try {
Log.Info(`connecting to ${this._url}`);
this._sock.open(this._url, this._wsProtocols);
this.sentEventsCounter+=1;
this._setLastActive();
} catch (e) {
if (e.name === 'SyntaxError') {
this._fail("Invalid host or port (" + e + ")");
@ -1301,8 +1304,6 @@ export default class RFB extends EventTargetMixin {
Math.floor(size.w), Math.floor(size.h),
this._screenID, this._screenFlags);
this.sentEventsCounter+=1;
Log.Debug('Requested new desktop size: ' +
size.w + 'x' + size.h);
}
@ -1582,6 +1583,7 @@ export default class RFB extends EventTargetMixin {
this._canvas);
}
this._setLastActive();
const mappedButton = this.mouseButtonMapper.get(ev.button);
switch (ev.type) {
case 'mousedown':
@ -1633,13 +1635,10 @@ export default class RFB extends EventTargetMixin {
// Otherwise we treat this as a mouse click event.
// Send the button down event here, as the button up
// event is sent at the end of this function.
this.sentEventsCounter+=1;
this._sendMouse(x, y, bmask);
}
}
this.sentEventsCounter+=1;
// Flush waiting move event first
if (this._mouseMoveTimer !== null) {
clearTimeout(this._mouseMoveTimer);
@ -3460,7 +3459,6 @@ export default class RFB extends EventTargetMixin {
RFB.messages.setMaxVideoResolution(this._sock,
this._maxVideoResolutionX,
this._maxVideoResolutionY);
this.sentEventsCounter+=1;
}
this._sock.rQskipBytes(1); // number-of-screens