157 lines
3.9 KiB
JavaScript
157 lines
3.9 KiB
JavaScript
var bricks = window.bricks || {};
|
|
/*
|
|
dependent on xterm.js
|
|
*/
|
|
bricks.Wterm = class extends bricks.JsWidget {
|
|
/*
|
|
{
|
|
ws_url:
|
|
ping_timeout:19
|
|
}
|
|
*/
|
|
constructor(opts){
|
|
super(opts);
|
|
this.socket = null;
|
|
this.ping_timeout = opts.ping_timeout || 19;
|
|
schedule_once(this.open.bind(this), 1);
|
|
this.bind('domon', this.send_term_size.bind(this));
|
|
this.bind('domoff', this.destroy.bind(this));
|
|
}
|
|
close_websocket(){
|
|
try {
|
|
console.log('socket alive, destroy it');
|
|
// this.socket.send(JSON.stringify({ type: "close"}));
|
|
this.socket.close(1000,'close now');
|
|
this.socket.onopen = null;
|
|
this.socket.onmessage = null;
|
|
this.socket.onerror = null;
|
|
this.socket.onclose = null;
|
|
this.socket = null;
|
|
} catch(e) {
|
|
this.socket = null;
|
|
console.log('e=', e);
|
|
}
|
|
}
|
|
close_terminal(){
|
|
try {
|
|
this.fitAddon.dispose();
|
|
this.term.dispose();
|
|
this.term = null;
|
|
} catch(e){
|
|
this.term = null;
|
|
console.log('e=', e);
|
|
}
|
|
}
|
|
destroy(){
|
|
console.debug('------domoff event, destory this widget');
|
|
try {
|
|
if (this.heartbeat_task){
|
|
this.heartbeat_task.cancel();
|
|
this.heartbeat_task = null;
|
|
}
|
|
this.unbind('element_resize', this.term_resize.bind(this))
|
|
} catch(e) {
|
|
console.log('error ', e);
|
|
}
|
|
console.debug('---1--domoff event, destory this widget');
|
|
if (this.socket){
|
|
this.close_websocket();
|
|
}
|
|
console.debug('---2--domoff event, destory this widget');
|
|
if (this.term){
|
|
this.close_terminal();
|
|
}
|
|
console.debug('---3--domoff event, destory this widget');
|
|
}
|
|
charsize_sizing(){
|
|
var cs = bricks.app.charsize;
|
|
this.term.setOption('fontSize', cs);
|
|
}
|
|
send_term_size(){
|
|
console.debug('------domon event, send the terminal size to server');
|
|
try {
|
|
console.log('resize():rows=', this.term.rows, this.term.cols);
|
|
this.socket.send(JSON.stringify({ type: "resize",
|
|
width:this.get_width(),
|
|
height: this.get_height(),
|
|
rows: this.term.rows,
|
|
cols: this.term.cols }));
|
|
} catch (e) {
|
|
console.log('ws not ready');
|
|
}
|
|
}
|
|
send_data(d){
|
|
this.socket.send(JSON.stringify({type: "input", "data":d}));
|
|
}
|
|
send_heartbeat(){
|
|
this.socket.send(JSON.stringify({ type: "heartbeat" }));
|
|
|
|
}
|
|
heartbeat(){
|
|
if (this.socket.readyState != 1) return;
|
|
this.send_heartbeat();
|
|
this.heartbeat_task = schedule_once(this.heartbeat.bind(this),
|
|
this.ping_timeout);
|
|
}
|
|
async open(){
|
|
var term_options = bricks.extend({width: "100%", height: "100%"}, this.term_options);
|
|
var term = new Terminal(term_options);
|
|
this.term = term;
|
|
term.open(this.dom_element);
|
|
// var sessdata = bricks.app.get_session();
|
|
// var ws = new WebSocket(this.opts.ws_url, sessdata);
|
|
var ws = new WebSocket(this.opts.ws_url);
|
|
this.socket = ws;
|
|
|
|
this.fitAddon = new FitAddon.FitAddon()
|
|
term.loadAddon(this.fitAddon)
|
|
this.fitAddon.fit();
|
|
this.charsize_sizing();
|
|
ws.onmessage = event => {
|
|
var msg = JSON.parse(event.data);
|
|
console.log('ws msg=', msg);
|
|
if (msg.data.type == 'heartbeat'){
|
|
console.log('connection alive');
|
|
} else if (msg.data.type == 'data') {
|
|
term.write(msg.data.data);
|
|
} else {
|
|
console.log('get server data = ', msg.data);
|
|
}
|
|
};
|
|
ws.onclose = (event) => {
|
|
console.log('websocket closed:', event.code, '--', event.reason);
|
|
if (this.heartbeat_task) {
|
|
this.heartbeat_task.cancel();
|
|
this.heartbeat_task = null;
|
|
}
|
|
};
|
|
ws.onopen = () => {
|
|
this.send_term_size();
|
|
this.bind('element_resize', this.term_resize.bind(this))
|
|
this.heartbeat_task = schedule_once(this.heartbeat.bind(this),
|
|
this.ping_timeout);
|
|
};
|
|
term.onData((key) => {
|
|
console.log('key=', key);
|
|
this.send_data(key);
|
|
});
|
|
term.onResize(({cols, rows}) =>{
|
|
this.send_term_size();
|
|
});
|
|
this.send_term_size();
|
|
term.focus();
|
|
}
|
|
term_resize(){
|
|
try {
|
|
console.log('widget resize event fired');
|
|
this.fitAddon.fit();
|
|
// this.send_term_size();
|
|
} catch(e){
|
|
console.log('resize error', e);
|
|
}
|
|
}
|
|
}
|
|
|
|
bricks.Factory.register('Wterm', bricks.Wterm);
|
|
|