vue-guacamole-client
Version:
A Vue.js based Guacamole client
124 lines (109 loc) • 3.47 kB
JavaScript
/**
* Contains the code relevant for creating and managing Guacamole connections.
*
* Only on guacamole connection can exists at a time for a given connection ID
*/
import Guacamole from 'guacamole-common-js'
export default{
methods: {
/**
* Creates the connection string to be appended as query parameters
* when creating a new Tunnel
*
* The hard codes the resolution of the VM, but scaling to make sure it fits in the
* browser will be handled elsewhere
*/
connectionString (id) {
return 'ID=' + encodeURIComponent(id) +
'&GUAC_WIDTH=1920' +
'&GUAC_HEIGHT=1080' +
'&GUAC_DPI=96'
},
/**
* Attempts to open a new Guacamole connection
*
* Requires Connection ID to be provided
*
* Will create new tunnel and client
*
* Will assign handlers for keyboard, mouse, error
* and state changes, and clipboard changes
*/
connect () {
// Do not proceed unless connection ID is provided
const identifier = this.connectionID
if (!identifier) return
// Existing connection, if it exists, must be cleaned up
// Failure to clean up will cause errors between conflicting
// event handlers
this.disconnect()
this.getTunnel()
this.client = new Guacamole.Client(this.tunnel)
this.getDisplay()
this.initErrorHandlers()
this.initClipboard()
this.initStateChangeHandlers()
this.initMouse()
this.initKeyboard()
// Connect
this.client.connect( this.connectionString(identifier) )
},
/**
* Attempts to cleanup an existing Guacamole connection
*
* Will destroy tunnel, client, and event handlers
*
* Must be called before new connections are made or keyboard event
* handlers will conflict with previous connection.
*/
disconnect () {
if (this.display && this.$refs.display) this.$refs.display.innerHTML = ''
try {
if (this.client) this.client.disconnect()
} catch (err) {
// Do nothing
} finally {
if (this.client) this.client.disconnect()
if (this.keyboard) {
this.keyboard.onkeydown = this.keyboard.onkeyup = null
}
if (this.mouse) {
this.mouse.onmousedown = this.mouse.onmouseup = this.mouse.onmousemove = null
}
this.client = null
this.display = null
this.tunnel = null
}
},
/**
* Create new tunnel for guac connection
*
* Attempts to create a web-socket (preferred)
* If browser doesn't support web-socket tunnel or WS tunnel fails it will fall back to HTTP
*/
getTunnel () {
if (window.WebSocket && this.webSocketTunnel && this.httpTunnel) {
this.tunnel = new Guacamole.ChainedTunnel(
new Guacamole.WebSocketTunnel( this.webSocketTunnel ),
new Guacamole.HTTPTunnel( this.httpTunnel, true )
)
} else if ( window.WebSocket && this.webSocketTunnel) {
this.tunnel = new Guacamole.ChainedTunnel(
new Guacamole.WebSocketTunnel( this.webSocketTunnel )
)
} else {
this.tunnel = new Guacamole.HTTPTunnel( this.httpTunnel, true )
}
}
},
/**
* Reconnect if connection id changes
*
* Attempts to disconnect and reconnect if the connection id changes
*/
watch: {
'connectionID': function(){
this.connect()
}
}
}