mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-544: Implement reconnect via GuacUI.Client.connect() function. Can be called again to reinitialize the UI and reconnect.
This commit is contained in:
@@ -76,81 +76,7 @@
|
|||||||
// Start connect after control returns from onload (allow browser
|
// Start connect after control returns from onload (allow browser
|
||||||
// to consider the page loaded).
|
// to consider the page loaded).
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
window.setTimeout(function() {
|
window.setTimeout(GuacUI.Client.connect, 0);
|
||||||
|
|
||||||
var tunnel;
|
|
||||||
|
|
||||||
// If WebSocket available, try to use it.
|
|
||||||
if (window.WebSocket)
|
|
||||||
tunnel = new Guacamole.ChainedTunnel(
|
|
||||||
new Guacamole.WebSocketTunnel("websocket-tunnel"),
|
|
||||||
new Guacamole.HTTPTunnel("tunnel")
|
|
||||||
);
|
|
||||||
|
|
||||||
// If no WebSocket, then use HTTP.
|
|
||||||
else
|
|
||||||
tunnel = new Guacamole.HTTPTunnel("tunnel");
|
|
||||||
|
|
||||||
// Instantiate client
|
|
||||||
var guac = new Guacamole.Client(tunnel);
|
|
||||||
|
|
||||||
// Add client to UI
|
|
||||||
guac.getDisplay().className = "software-cursor";
|
|
||||||
GuacUI.Client.display.appendChild(guac.getDisplay());
|
|
||||||
|
|
||||||
// Tie UI to client
|
|
||||||
GuacUI.Client.attach(guac);
|
|
||||||
|
|
||||||
// Calculate optimal width/height for display
|
|
||||||
var pixel_density = window.devicePixelRatio || 1;
|
|
||||||
var optimal_dpi = pixel_density * 96;
|
|
||||||
var optimal_width = window.innerWidth * pixel_density;
|
|
||||||
var optimal_height = window.innerHeight * pixel_density;
|
|
||||||
|
|
||||||
// Scale width/height to be at least 600x600
|
|
||||||
if (optimal_width < 600 || optimal_height < 600) {
|
|
||||||
var scale = Math.max(600 / optimal_width, 600 / optimal_height);
|
|
||||||
optimal_width = optimal_width * scale;
|
|
||||||
optimal_height = optimal_height * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get entire query string, and pass to connect().
|
|
||||||
// Normally, only the "id" parameter is required, but
|
|
||||||
// all parameters should be preserved and passed on for
|
|
||||||
// the sake of authentication.
|
|
||||||
|
|
||||||
var connect_string =
|
|
||||||
window.location.search.substring(1)
|
|
||||||
+ "&width=" + Math.floor(optimal_width)
|
|
||||||
+ "&height=" + Math.floor(optimal_height)
|
|
||||||
+ "&dpi=" + Math.floor(optimal_dpi);
|
|
||||||
|
|
||||||
// Add audio mimetypes to connect_string
|
|
||||||
GuacUI.Audio.supported.forEach(function(mimetype) {
|
|
||||||
connect_string += "&audio=" + encodeURIComponent(mimetype);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add video mimetypes to connect_string
|
|
||||||
GuacUI.Video.supported.forEach(function(mimetype) {
|
|
||||||
connect_string += "&video=" + encodeURIComponent(mimetype);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show connection errors from tunnel
|
|
||||||
tunnel.onerror = function(status) {
|
|
||||||
var message = GuacUI.Client.tunnel_errors[status.code] || GuacUI.Client.tunnel_errors.DEFAULT;
|
|
||||||
GuacUI.Client.showError("Connection Error", message);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Notify of disconnections (if not already notified of something else)
|
|
||||||
tunnel.onstatechange = function(state) {
|
|
||||||
if (state === Guacamole.Tunnel.State.CLOSED && !GuacUI.Client.visibleStatus)
|
|
||||||
GuacUI.Client.showStatus("Disconnected", "You have been disconnected. Reload the page to reconnect.");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Connect
|
|
||||||
guac.connect(connect_string);
|
|
||||||
|
|
||||||
}, 0);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ]]> */ </script>
|
/* ]]> */ </script>
|
||||||
|
@@ -828,16 +828,99 @@ GuacUI.Client.showError = function(title, status) {
|
|||||||
GuacUI.Client.visibleStatus =
|
GuacUI.Client.visibleStatus =
|
||||||
new GuacUI.Client.ModalStatus(title, status, "guac-error");
|
new GuacUI.Client.ModalStatus(title, status, "guac-error");
|
||||||
GuacUI.Client.visibleStatus.show();
|
GuacUI.Client.visibleStatus.show();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the current Guacamole connection, attaching a new Guacamole
|
||||||
|
* client to the user interface. If a Guacamole client is already attached,
|
||||||
|
* it is replaced.
|
||||||
|
*/
|
||||||
|
GuacUI.Client.connect = function() {
|
||||||
|
|
||||||
|
var tunnel;
|
||||||
|
|
||||||
|
// If WebSocket available, try to use it.
|
||||||
|
if (window.WebSocket)
|
||||||
|
tunnel = new Guacamole.ChainedTunnel(
|
||||||
|
new Guacamole.WebSocketTunnel("websocket-tunnel"),
|
||||||
|
new Guacamole.HTTPTunnel("tunnel")
|
||||||
|
);
|
||||||
|
|
||||||
|
// If no WebSocket, then use HTTP.
|
||||||
|
else
|
||||||
|
tunnel = new Guacamole.HTTPTunnel("tunnel");
|
||||||
|
|
||||||
|
// Instantiate client
|
||||||
|
var guac = new Guacamole.Client(tunnel);
|
||||||
|
|
||||||
|
// Tie UI to client
|
||||||
|
GuacUI.Client.attach(guac);
|
||||||
|
|
||||||
|
// Calculate optimal width/height for display
|
||||||
|
var pixel_density = window.devicePixelRatio || 1;
|
||||||
|
var optimal_dpi = pixel_density * 96;
|
||||||
|
var optimal_width = window.innerWidth * pixel_density;
|
||||||
|
var optimal_height = window.innerHeight * pixel_density;
|
||||||
|
|
||||||
|
// Scale width/height to be at least 600x600
|
||||||
|
if (optimal_width < 600 || optimal_height < 600) {
|
||||||
|
var scale = Math.max(600 / optimal_width, 600 / optimal_height);
|
||||||
|
optimal_width = optimal_width * scale;
|
||||||
|
optimal_height = optimal_height * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get entire query string, and pass to connect().
|
||||||
|
// Normally, only the "id" parameter is required, but
|
||||||
|
// all parameters should be preserved and passed on for
|
||||||
|
// the sake of authentication.
|
||||||
|
|
||||||
|
var connect_string =
|
||||||
|
window.location.search.substring(1)
|
||||||
|
+ "&width=" + Math.floor(optimal_width)
|
||||||
|
+ "&height=" + Math.floor(optimal_height)
|
||||||
|
+ "&dpi=" + Math.floor(optimal_dpi);
|
||||||
|
|
||||||
|
// Add audio mimetypes to connect_string
|
||||||
|
GuacUI.Audio.supported.forEach(function(mimetype) {
|
||||||
|
connect_string += "&audio=" + encodeURIComponent(mimetype);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add video mimetypes to connect_string
|
||||||
|
GuacUI.Video.supported.forEach(function(mimetype) {
|
||||||
|
connect_string += "&video=" + encodeURIComponent(mimetype);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show connection errors from tunnel
|
||||||
|
tunnel.onerror = function(status) {
|
||||||
|
var message = GuacUI.Client.tunnel_errors[status.code] || GuacUI.Client.tunnel_errors.DEFAULT;
|
||||||
|
GuacUI.Client.showError("Connection Error", message);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Notify of disconnections (if not already notified of something else)
|
||||||
|
tunnel.onstatechange = function(state) {
|
||||||
|
if (state === Guacamole.Tunnel.State.CLOSED && !GuacUI.Client.visibleStatus)
|
||||||
|
GuacUI.Client.showStatus("Disconnected", "You have been disconnected. Reload the page to reconnect.");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Connect
|
||||||
|
guac.connect(connect_string);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches a Guacamole.Client to the client UI, such that Guacamole events
|
* Attaches a Guacamole.Client to the client UI, such that Guacamole events
|
||||||
* affect the UI, and local events affect the Guacamole.Client.
|
* affect the UI, and local events affect the Guacamole.Client. If a client
|
||||||
|
* is already attached, it is replaced.
|
||||||
*
|
*
|
||||||
* @param {Guacamole.Client} guac The Guacamole.Client to attach to the UI.
|
* @param {Guacamole.Client} guac The Guacamole.Client to attach to the UI.
|
||||||
*/
|
*/
|
||||||
GuacUI.Client.attach = function(guac) {
|
GuacUI.Client.attach = function(guac) {
|
||||||
|
|
||||||
|
// If a client is already attached, ensure it is disconnected
|
||||||
|
if (GuacUI.Client.attachedClient)
|
||||||
|
GuacUI.Client.attachedClient.disconnect();
|
||||||
|
|
||||||
// Store attached client
|
// Store attached client
|
||||||
GuacUI.Client.attachedClient = guac;
|
GuacUI.Client.attachedClient = guac;
|
||||||
|
|
||||||
@@ -850,7 +933,7 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
|
|
||||||
guac.onresize = function(width, height) {
|
guac.onresize = function(width, height) {
|
||||||
GuacUI.Client.updateDisplayScale();
|
GuacUI.Client.updateDisplayScale();
|
||||||
}
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update UI when the state of the Guacamole.Client changes.
|
* Update UI when the state of the Guacamole.Client changes.
|
||||||
@@ -1054,6 +1137,21 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hide any existing status notifications
|
||||||
|
GuacUI.Client.hideStatus();
|
||||||
|
|
||||||
|
// Remove old client from UI, if any
|
||||||
|
GuacUI.Client.display.innerHTML = "";
|
||||||
|
|
||||||
|
// Add client to UI
|
||||||
|
guac.getDisplay().className = "software-cursor";
|
||||||
|
GuacUI.Client.display.appendChild(guac.getDisplay());
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// One-time UI initialization
|
||||||
|
(function() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Route document-level keyboard events to the client.
|
* Route document-level keyboard events to the client.
|
||||||
*/
|
*/
|
||||||
@@ -1063,6 +1161,10 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
|
|
||||||
keyboard.onkeydown = function (keysym) {
|
keyboard.onkeydown = function (keysym) {
|
||||||
|
|
||||||
|
// Only handle key events if client is attached
|
||||||
|
var guac = GuacUI.Client.attachedClient;
|
||||||
|
if (!guac) return;
|
||||||
|
|
||||||
// Handle Ctrl-shortcuts specifically
|
// Handle Ctrl-shortcuts specifically
|
||||||
if (keyboard.modifiers.ctrl && !keyboard.modifiers.alt && !keyboard.modifiers.shift) {
|
if (keyboard.modifiers.ctrl && !keyboard.modifiers.alt && !keyboard.modifiers.shift) {
|
||||||
|
|
||||||
@@ -1086,25 +1188,30 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
guac.sendKeyEvent(1, keysym);
|
guac.sendKeyEvent(1, keysym);
|
||||||
|
|
||||||
// If key is NOT one of the expected keys, gesture not possible
|
// If key is NOT one of the expected keys, gesture not possible
|
||||||
if (keysym != 0xFFE3 && keysym != 0xFFE9 && keysym != 0xFFE1)
|
if (keysym !== 0xFFE3 && keysym !== 0xFFE9 && keysym !== 0xFFE1)
|
||||||
show_keyboard_gesture_possible = false;
|
show_keyboard_gesture_possible = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
keyboard.onkeyup = function (keysym) {
|
keyboard.onkeyup = function (keysym) {
|
||||||
|
|
||||||
|
// Only handle key events if client is attached
|
||||||
|
var guac = GuacUI.Client.attachedClient;
|
||||||
|
if (!guac) return;
|
||||||
|
|
||||||
guac.sendKeyEvent(0, keysym);
|
guac.sendKeyEvent(0, keysym);
|
||||||
|
|
||||||
// If lifting up on shift, toggle keyboard if rest of gesture
|
// If lifting up on shift, toggle keyboard if rest of gesture
|
||||||
// conditions satisfied
|
// conditions satisfied
|
||||||
if (show_keyboard_gesture_possible && keysym == 0xFFE1) {
|
if (show_keyboard_gesture_possible && keysym === 0xFFE1) {
|
||||||
if (keyboard.pressed[0xFFE3] && keyboard.pressed[0xFFE9]) {
|
if (keyboard.pressed[0xFFE3] && keyboard.pressed[0xFFE9]) {
|
||||||
|
|
||||||
// If in INTERACTIVE mode, switch to OSK
|
// If in INTERACTIVE mode, switch to OSK
|
||||||
if (GuacUI.StateManager.getState() == GuacUI.Client.states.INTERACTIVE)
|
if (GuacUI.StateManager.getState() === GuacUI.Client.states.INTERACTIVE)
|
||||||
GuacUI.StateManager.setState(GuacUI.Client.states.OSK);
|
GuacUI.StateManager.setState(GuacUI.Client.states.OSK);
|
||||||
|
|
||||||
// If in OSK mode, switch to INTERACTIVE
|
// If in OSK mode, switch to INTERACTIVE
|
||||||
else if (GuacUI.StateManager.getState() == GuacUI.Client.states.OSK)
|
else if (GuacUI.StateManager.getState() === GuacUI.Client.states.OSK)
|
||||||
GuacUI.StateManager.setState(GuacUI.Client.states.INTERACTIVE);
|
GuacUI.StateManager.setState(GuacUI.Client.states.INTERACTIVE);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1140,7 +1247,8 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
// Set remote clipboard contents on paste
|
// Set remote clipboard contents on paste
|
||||||
document.body.addEventListener("paste", function handle_paste(e) {
|
document.body.addEventListener("paste", function handle_paste(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
guac.setClipboard(e.clipboardData.getData("text/plain"));
|
if (GuacUI.Client.attachedClient)
|
||||||
|
GuacUI.Client.attachedClient.setClipboard(e.clipboardData.getData("text/plain"));
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1149,7 +1257,9 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
window.onunload = function() {
|
window.onunload = function() {
|
||||||
|
|
||||||
GuacUI.Client.updateThumbnail();
|
GuacUI.Client.updateThumbnail();
|
||||||
guac.disconnect();
|
|
||||||
|
if (GuacUI.Client.attachedClient)
|
||||||
|
GuacUI.Client.attachedClient.disconnect();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1162,15 +1272,17 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
var width = window.innerWidth * pixel_density;
|
var width = window.innerWidth * pixel_density;
|
||||||
var height = window.innerHeight * pixel_density;
|
var height = window.innerHeight * pixel_density;
|
||||||
|
|
||||||
guac.sendSize(width, height);
|
if (GuacUI.Client.attachedClient)
|
||||||
|
GuacUI.Client.attachedClient.sendSize(width, height);
|
||||||
|
|
||||||
GuacUI.Client.updateDisplayScale();
|
GuacUI.Client.updateDisplayScale();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GuacUI.sessionState.onchange = function(old_state, new_state, name) {
|
GuacUI.sessionState.onchange = function(old_state, new_state, name) {
|
||||||
if (name == "clipboard")
|
if (name === "clipboard" && GuacUI.Client.attachedClient)
|
||||||
guac.setClipboard(new_state[name]);
|
GuacUI.Client.attachedClient.setClipboard(new_state[name]);
|
||||||
else if (name == "auto-fit")
|
else if (name === "auto-fit")
|
||||||
GuacUI.Client.updateDisplayScale();
|
GuacUI.Client.updateDisplayScale();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1213,7 +1325,7 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
GuacUI.Client.display.addEventListener('touchstart', function(e) {
|
GuacUI.Client.display.addEventListener('touchstart', function(e) {
|
||||||
|
|
||||||
// Record touch location
|
// Record touch location
|
||||||
if (e.touches.length == 1) {
|
if (e.touches.length === 1) {
|
||||||
var touch = e.touches[0];
|
var touch = e.touches[0];
|
||||||
long_press_start_x = touch.screenX;
|
long_press_start_x = touch.screenX;
|
||||||
long_press_start_y = touch.screenY;
|
long_press_start_y = touch.screenY;
|
||||||
@@ -1353,6 +1465,9 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// Ignore file drops if no attached client
|
||||||
|
if (!GuacUI.Client.attachedClient) return;
|
||||||
|
|
||||||
// Upload each file
|
// Upload each file
|
||||||
var files = e.dataTransfer.files;
|
var files = e.dataTransfer.files;
|
||||||
for (var i=0; i<files.length; i++)
|
for (var i=0; i<files.length; i++)
|
||||||
@@ -1360,5 +1475,4 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
|
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
};
|
})();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user