UNPKG

opennebula-guacamole

Version:

guacamole server in node.js. RDP/VNC client for HTML5 browsers

168 lines (144 loc) 5.06 kB
const EventEmitter = require('events').EventEmitter; const { Server: WsServer } = require('ws'); const DeepExtend = require('deep-extend'); const ClientConnection = require('./ClientConnection.js'); class Server extends EventEmitter { constructor(wsOptions, guacdOptions, clientOptions, callbacks) { super(); this.LOGLEVEL = { QUIET: 0, ERRORS: 10, NORMAL: 20, VERBOSE: 30, DEBUG: 40, }; if (wsOptions.hasOwnProperty('server')) { this.wsOptions = wsOptions; } else { this.wsOptions = Object.assign({ port: 8080 }, wsOptions); } this.guacdOptions = Object.assign({ host: '127.0.0.1', port: 4822 }, guacdOptions); this.clientOptions = {}; DeepExtend(this.clientOptions, { log: { level: this.LOGLEVEL.VERBOSE, stdLog: console.log, errorLog: console.error }, crypt: { cypher: 'AES-256-CBC', }, connectionDefaultSettings: { rdp: { 'args': 'connect', 'port': '3389', 'width': 1024, 'height': 768, 'dpi': 96, }, vnc: { 'args': 'connect', 'port': '5900', 'width': 1024, 'height': 768, 'dpi': 96, }, ssh: { 'args': 'connect', 'port': 22, 'width': 1024, 'height': 768, 'dpi': 96, }, telnet: { 'args': 'connect', 'port': 23, 'width': 1024, 'height': 768, 'dpi': 96, } }, allowedUnencryptedConnectionSettings: { rdp: [ 'width', 'height', 'dpi' ], vnc: [ 'width', 'height', 'dpi' ], ssh: [ 'color-scheme', 'font-name', 'font-size', 'width', 'height', 'dpi' ], telnet: [ 'color-scheme', 'font-name', 'font-size', 'width', 'height', 'dpi' ] } }, clientOptions); // Backwards compatibility if (this.clientOptions.log.verbose !== 'undefined' && this.clientOptions.log.verbose === true) { this.clientOptions.log.level = this.LOGLEVEL.DEBUG; } if (typeof this.clientOptions.log.level === 'string' && this.LOGLEVEL[this.clientOptions.log.level]) { this.clientOptions.log.level = this.LOGLEVEL[this.clientOptions.log.level]; } this.callbacks = Object.assign({ processConnectionSettings: (settings, callback, connectionsWS) => callback(undefined, settings, connectionsWS), processConnectionClose: (err, connectionsWS) => undefined, }, callbacks); this.connectionsCount = 0; this.activeConnections = new Map(); if (this.clientOptions.log.level >= this.LOGLEVEL.NORMAL) { this.clientOptions.log.stdLog('Starting guacamole-lite websocket server'); } this.webSocketServer = new WsServer(this.wsOptions); this.webSocketServer.on('connection', this.newConnection.bind(this)); process.on('SIGTERM', this.close.bind(this)); process.on('SIGINT', this.close.bind(this)); } close() { if (this.clientOptions.log.level >= this.LOGLEVEL.NORMAL) { this.clientOptions.log.stdLog('Closing all connections and exiting...'); } this.webSocketServer.close(() => { this.activeConnections.forEach((activeConnection) => { if(activeConnection && activeConnection.ws){ activeConnection.ws.close(); } }); }); } newConnection(webSocketConnection) { this.connectionsCount++; const newConnection = new ClientConnection(this, this.connectionsCount, webSocketConnection) const dataConnection = this.activeConnections.get(this.connectionsCount) if(dataConnection){ dataConnection.ws = newConnection }else{ this.activeConnections.set( this.connectionsCount, { ws: newConnection } ); } } } module.exports = Server;