From 34bab9524eb6d1b5e3fa96be7ed2602d71f25dd9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 6 Sep 2018 19:57:29 -0700 Subject: [PATCH] GUACAMOLE-567: Regularly test connection stability of HTTP tunnel. Unlike the WebSocket tunnel, where a manual ping request/response must be explicitly implemented, we can rely on HTTP's own request/response to verify stability. --- .../src/main/webapp/modules/Tunnel.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/guacamole-common-js/src/main/webapp/modules/Tunnel.js b/guacamole-common-js/src/main/webapp/modules/Tunnel.js index 827dd6cd4..24ffaa860 100644 --- a/guacamole-common-js/src/main/webapp/modules/Tunnel.js +++ b/guacamole-common-js/src/main/webapp/modules/Tunnel.js @@ -258,6 +258,25 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain, extraTunnelHeaders) { */ var unstableTimeout = null; + /** + * The current connection stability test ping interval ID, if any. This + * will only be set upon successful connection. + * + * @private + * @type {Number} + */ + var pingInterval = null; + + /** + * The number of milliseconds to wait between connection stability test + * pings. + * + * @private + * @constant + * @type {Number} + */ + var PING_FREQUENCY = 500; + /** * Additional headers to be sent in tunnel requests. This dictionary can be * populated with key/value header pairs to pass information such as authentication @@ -327,6 +346,9 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain, extraTunnelHeaders) { window.clearTimeout(receive_timeout); window.clearTimeout(unstableTimeout); + // Cease connection test pings + window.clearInterval(pingInterval); + // Ignore if already closed if (tunnel.state === Guacamole.Tunnel.State.CLOSED) return; @@ -413,6 +435,8 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain, extraTunnelHeaders) { message_xmlhttprequest.onreadystatechange = function() { if (message_xmlhttprequest.readyState === 4) { + reset_timeout(); + // If an error occurs during send, handle it if (message_xmlhttprequest.status !== 200) handleHTTPTunnelError(message_xmlhttprequest); @@ -687,6 +711,11 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain, extraTunnelHeaders) { // Mark as open tunnel.setState(Guacamole.Tunnel.State.OPEN); + // Ping tunnel endpoint regularly to test connection stability + pingInterval = setInterval(function sendPing() { + tunnel.sendMessage("nop"); + }, PING_FREQUENCY); + // Start reading data handleResponse(makeRequest());