diff --git a/demo/app.js b/demo/app.js index 8661cc62..83195e62 100644 --- a/demo/app.js +++ b/demo/app.js @@ -4,6 +4,9 @@ var expressWs = require('express-ws')(app); var os = require('os'); var pty = require('pty.js'); +var terminals = {}, + logs = {}; + app.use('/src', express.static(__dirname + '/../src')); app.use('/addons', express.static(__dirname + '/../addons')); @@ -19,17 +22,43 @@ app.get('/main.js', function(req, res){ res.sendFile(__dirname + '/main.js'); }); -app.ws('/bash', function(ws, req) { - /** - * Open bash terminal and attach it - */ - var term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], { - name: 'xterm-color', - cols: 80, - rows: 24, - cwd: process.env.PWD, - env: process.env +app.post('/terminals', function (req, res) { + var cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], { + name: 'xterm-color', + cols: cols || 80, + rows: rows || 24, + cwd: process.env.PWD, + env: process.env + }); + + console.log('Created terminal with PID: ' + term.pid); + terminals[term.pid] = term; + logs[term.pid] = ''; + term.on('data', function(data) { + logs[term.pid] += data; }); + res.send(term.pid.toString()); + res.end(); +}); + +app.post('/terminals/:pid/size', function (req, res) { + var pid = parseInt(req.params.pid), + cols = parseInt(req.query.cols), + rows = parseInt(req.query.rows), + term = terminals[pid]; + + term.resize(cols, rows); + console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.'); + res.end(); +}); + +app.ws('/terminals/:pid', function (ws, req) { + var term = terminals[parseInt(req.params.pid)]; + console.log('Connected to terminal ' + term.pid); + ws.send(logs[term.pid]); + term.on('data', function(data) { try { ws.send(data); @@ -41,8 +70,11 @@ app.ws('/bash', function(ws, req) { term.write(msg); }); ws.on('close', function () { - console.log('close'); process.kill(term.pid); + console.log('Closed terminal ' + term.pid); + // Clean things up + delete terminals[term.pid]; + delete logs[term.pid]; }); }); diff --git a/demo/main.js b/demo/main.js index 59bdacdd..b46716bf 100644 --- a/demo/main.js +++ b/demo/main.js @@ -1,7 +1,8 @@ var term, protocol, socketURL, - socket; + socket, + pid; var terminalContainer = document.getElementById('terminal-container'); var optionElements = { @@ -13,22 +14,39 @@ optionElements.cursorBlink.addEventListener('change', createTerminal); createTerminal(); function createTerminal() { + // Clean terminal while (terminalContainer.children.length) { terminalContainer.removeChild(terminalContainer.children[0]); } term = new Terminal({ cursorBlink: optionElements.cursorBlink.checked }); + term.on('resize', function (size) { + if (!pid) { + return; + } + }); protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; - socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/bash'; - socket = new WebSocket(socketURL); + socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/'; term.open(terminalContainer); - term.fit(); - socket.onopen = runRealTerminal; - socket.onclose = runFakeTerminal; - socket.onerror = runFakeTerminal; + var initialGeometry = term.proposeGeometry(), + cols = initialGeometry.cols, + rows = initialGeometry.rows; + + fetch('/terminals?cols=' + cols + '&rows=' + rows, {method: 'POST'}).then(function (res) { + res.text().then(function (pid) { + window.pid = pid; + socketURL += pid; + socket = new WebSocket(socketURL); + socket.onopen = runRealTerminal; + socket.onclose = runFakeTerminal; + socket.onerror = runFakeTerminal; + }); + }); + + term.fit(); }