Commit c439f2b6 by Sheng

Instantly update pseudo-terminal size by client terminal size

parent 82929ea4
...@@ -136,5 +136,5 @@ class TestApp(AsyncHTTPTestCase): ...@@ -136,5 +136,5 @@ class TestApp(AsyncHTTPTestCase):
ws = yield tornado.websocket.websocket_connect(ws_url) ws = yield tornado.websocket.websocket_connect(ws_url)
msg = yield ws.read_message() msg = yield ws.read_message()
self.assertIn(b'Welcome!', msg) self.assertIn(b'Welcome!', msg)
yield ws.write_message('bye') yield ws.write_message(json.dumps({'resize': [79, 23], 'data': 'bye'}))
ws.close() ws.close()
import io import io
import json
import logging import logging
import socket import socket
import threading import threading
...@@ -199,8 +200,17 @@ class WsockHandler(MixinHandler, tornado.websocket.WebSocketHandler): ...@@ -199,8 +200,17 @@ class WsockHandler(MixinHandler, tornado.websocket.WebSocketHandler):
def on_message(self, message): def on_message(self, message):
logging.debug('{!r} from {}:{}'.format(message, *self.src_addr)) logging.debug('{!r} from {}:{}'.format(message, *self.src_addr))
worker = self.worker_ref() worker = self.worker_ref()
worker.data_to_dst.append(message) msg = json.loads(message)
worker.on_write() resize = msg.get('resize')
if resize:
try:
worker.chan.resize_pty(*resize)
except paramiko.SSHException:
pass
data = msg.get('data')
if data:
worker.data_to_dst.append(data)
worker.on_write()
def on_close(self): def on_close(self):
logging.info('Disconnected from {}:{}'.format(*self.src_addr)) logging.info('Disconnected from {}:{}'.format(*self.src_addr))
......
...@@ -38,6 +38,7 @@ jQuery(function($){ ...@@ -38,6 +38,7 @@ jQuery(function($){
}); });
function parse_xterm_style() { function parse_xterm_style() {
var text = $('.xterm-helpers style').text(); var text = $('.xterm-helpers style').text();
var arr = text.split('xterm-normal-char{width:'); var arr = text.split('xterm-normal-char{width:');
...@@ -46,13 +47,28 @@ jQuery(function($){ ...@@ -46,13 +47,28 @@ jQuery(function($){
style.height = parseInt(arr[1]); style.height = parseInt(arr[1]);
} }
function current_geometry() { function current_geometry() {
if (!style.width || !style.height) { if (!style.width || !style.height) {
parse_xterm_style(); parse_xterm_style();
} }
cols = parseInt(window.innerWidth / style.width); cols = parseInt(window.innerWidth / style.width);
rows = parseInt(window.innerHeight / style.height); rows = parseInt(window.innerHeight / style.height);
return [cols, rows]; return {'cols': cols, 'rows': rows};
}
function resize_term(term, socket) {
var geometry = current_geometry(),
cols = geometry.cols,
rows = geometry.rows;
// console.log([cols, rows]);
// console.log(term.geometry);
if (cols != term.geometry[0] || rows != term.geometry[1]) {
console.log('resizing term');
term.resize(cols, rows);
socket.send(JSON.stringify({'resize': [cols, rows]}));
}
} }
...@@ -69,19 +85,16 @@ jQuery(function($){ ...@@ -69,19 +85,16 @@ jQuery(function($){
var ws_url = window.location.href.replace('http', 'ws'), var ws_url = window.location.href.replace('http', 'ws'),
join = (ws_url[ws_url.length-1] == '/' ? '' : '/'), join = (ws_url[ws_url.length-1] == '/' ? '' : '/'),
url = ws_url + join + 'ws?id=' + msg.id, url = ws_url + join + 'ws?id=' + msg.id,
socket = new WebSocket(url), terminal = document.getElementById('#terminal');
terminal = document.getElementById('#terminal'), socket = new WebSocket(url);
geometry = current_geometry();
term = new Terminal({ term = new Terminal({
cursorBlink: true, cursorBlink: true,
cols: geometry[0],
rows: geometry[1]
}); });
console.log(url); console.log(url);
term.on('data', function(data) { term.on('data', function(data) {
// console.log(data); // console.log(data);
socket.send(data); socket.send(JSON.stringify({'data': data}));
}); });
socket.onopen = function(e) { socket.onopen = function(e) {
...@@ -93,10 +106,14 @@ jQuery(function($){ ...@@ -93,10 +106,14 @@ jQuery(function($){
socket.onmessage = function(msg) { socket.onmessage = function(msg) {
var reader = new FileReader(); var reader = new FileReader();
reader.onloadend = function(event){ reader.onloadend = function(event){
var decoder = new TextDecoder(); var decoder = new TextDecoder();
var text = decoder.decode(reader.result); var text = decoder.decode(reader.result);
// console.log(text); // console.log(text);
term.write(text); term.write(text);
if (!term.resized) {
resize_term(term, socket);
term.resized = true;
}
}; };
reader.readAsArrayBuffer(msg.data); reader.readAsArrayBuffer(msg.data);
}; };
...@@ -108,17 +125,18 @@ jQuery(function($){ ...@@ -108,17 +125,18 @@ jQuery(function($){
socket.onclose = function(e) { socket.onclose = function(e) {
console.log(e); console.log(e);
term.destroy(); term.destroy();
term = undefined;
socket = undefined;
$('.container').show(); $('.container').show();
status.text(e.reason); status.text(e.reason);
btn.prop('disabled', false); btn.prop('disabled', false);
}; };
} }
$(window).resize(function(){ $(window).resize(function(){
if (typeof term != 'undefined') { if (typeof term != 'undefined' && typeof socket != 'undefined') {
geometry = current_geometry(); resize_term(term, socket);
term.geometry = geometry;
term.resize(geometry[0], geometry[1]);
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment