202 lines
7.0 KiB
JavaScript
Executable File
202 lines
7.0 KiB
JavaScript
Executable File
/**
|
||
这里是非iframe版本的openTerminal
|
||
TODO 换一个消息机制,替代iframe情况下使用的postMessage
|
||
消息得种类有:
|
||
发送
|
||
1、postMessage({tp: 'sshWorking'}, "*"); ssh正在被使用
|
||
2、window.parent.postMessage({tp: 'setSSHConnectStatus', tab: options.tab}, "*");
|
||
|
||
接收
|
||
1、 if(event.data.tp === 'resize'){ 改变命令行窗体大小
|
||
2、 } else if (event.data.tp === 'reload') { 异常中断后重连
|
||
3、 } else if (event.data.tp === 'close_ssh_cocket') { 中断命令行websocket
|
||
*/
|
||
function openTerminal(options) {
|
||
// 为了多个实例能同时存在
|
||
(function () {
|
||
var heartBeatInterval;
|
||
var force_close_socket = false;
|
||
//var CONNECT_TIME = 0; // 请求连接次数
|
||
Rows = parseInt(options.rows);
|
||
var parentDomId = options.parentDomId || ''
|
||
var client = new WSSHClient();
|
||
var base64 = new Base64();
|
||
var term = new Terminal({
|
||
cols: options.columns, rows: Rows, screenKeys: true, useStyle: true
|
||
// TODO 默认是canvas,可能被其他样式影响了 canvas用不了
|
||
, rendererType: 'dom'
|
||
, fontSize: 16
|
||
});
|
||
term.on('data', function (data) {
|
||
console.log("xterm data: ");
|
||
console.log(data);
|
||
client.sendClientData(data);
|
||
|
||
window.parent.postMessage({ tp: 'sshWorking' }, "*");
|
||
});
|
||
term.open();
|
||
$('body>.terminal').detach().appendTo(parentDomId + ' #term');
|
||
$(parentDomId + " #term").show();
|
||
term.write("Connecting...");
|
||
console.log(options)
|
||
console.debug(options);
|
||
|
||
//var interTime = setInterval(client_connect, 1000)
|
||
setTimeout(client_connect, 3000);
|
||
|
||
heartBeatInterval = setInterval(function () {
|
||
client.sendHeartBeat()
|
||
}, 30 * 1000)
|
||
/**
|
||
* 重新设置窗口大小
|
||
* @param o
|
||
*/
|
||
var resizeTerminal = function (o) {
|
||
if (typeof term === 'object') {
|
||
var rows = term.rows;
|
||
var cols = term.cols;
|
||
if (o.rows > 0) {
|
||
rows = o.rows;
|
||
}
|
||
if (o.cols > 0) {
|
||
cols = o.cols;
|
||
}
|
||
term.resize(cols, rows);
|
||
}
|
||
};
|
||
|
||
window.addEventListener("message", function (event) {
|
||
console.log("post message: ");
|
||
console.log(event.data);
|
||
if (event.data.tp === 'resize') {
|
||
resizeTerminal(event.data);
|
||
} else if (event.data.tp === 'reload') {
|
||
window.location.reload()
|
||
} else if (event.data.tp === 'close_ssh_cocket') {
|
||
force_close_socket = true; // 强制关闭socket,用于不开启自动重连
|
||
client && client.close();
|
||
}
|
||
}, false);
|
||
|
||
var intervalId = null;
|
||
function client_connect() {
|
||
var CONNECTED = false; // 是否连接成功过
|
||
console.log("连接中....");
|
||
console.log(options);
|
||
|
||
client.connect({
|
||
onError: function (error) {
|
||
term.write('Error: ' + error + '\r\n');
|
||
console.log('error happened');
|
||
},
|
||
onConnect: function () {
|
||
console.log('connection established');
|
||
client.sendInitData(options);
|
||
term.focus();
|
||
},
|
||
onClose: function () {
|
||
|
||
clearInterval(heartBeatInterval);
|
||
|
||
console.log("连接关闭");
|
||
term.write("\r\nconnection closed");
|
||
if (CONNECTED) {
|
||
console.log('connection reset by peer');
|
||
$('term').hide();
|
||
}
|
||
if (force_close_socket === false) {
|
||
// $(window).trigger('setSSHConnectStatus');
|
||
window.parent.postMessage({ tp: 'setSSHConnectStatus', tab: options.tab }, "*");
|
||
} else {
|
||
// 主动关闭连接时,不自动重连
|
||
force_close_socket = false;
|
||
}
|
||
},
|
||
onData: function (data) {
|
||
if (!CONNECTED) {
|
||
console.log("first connected.");
|
||
// 问题重现的实训 带代码tab的 命令行实训 https://www.educoder.net/tasks/83hflni9es7tl
|
||
setTimeout(function () {
|
||
// TODO canvas模式下,没有body
|
||
if (term && term.body && term.body.innerText
|
||
&& term.body.innerText.indexOf('Connecting') != -1) {
|
||
term.clear(); // 有的连上后还出现了“Connecting。。。”
|
||
}
|
||
}, 1000)
|
||
|
||
term.write("\r"); //换行
|
||
term.focus(); //焦点移动到框上
|
||
}
|
||
/*if(interTime){
|
||
clearInterval(interTime);
|
||
}*/
|
||
CONNECTED = true;
|
||
|
||
data = base64.decode(data);
|
||
/* TIMEINIT = 0;*/
|
||
term.write(data);
|
||
console.log('get data:' + data);
|
||
}
|
||
})
|
||
}
|
||
}());
|
||
}
|
||
|
||
var charWidth = 6.2;
|
||
var charHeight = 15.2;
|
||
|
||
/**
|
||
* for full screen
|
||
* @returns {{w: number, h: number}}
|
||
*/
|
||
function getTerminalSize() {
|
||
var width = window.innerWidth;
|
||
var height = window.innerHeight;
|
||
return {
|
||
w: Math.floor(width / charWidth),
|
||
h: Math.floor(height / charHeight)
|
||
};
|
||
}
|
||
|
||
|
||
function store(options) {
|
||
window.localStorage.host = options.host
|
||
window.localStorage.port = options.port
|
||
window.localStorage.username = options.username
|
||
window.localStorage.ispwd = options.ispwd;
|
||
window.localStorage.secret = options.secret
|
||
}
|
||
|
||
function check() {
|
||
return validResult["host"] && validResult["port"] && validResult["username"];
|
||
}
|
||
|
||
function connect() {
|
||
var remember = $("#remember").is(":checked")
|
||
var options = {
|
||
host: $("#host").val(),
|
||
port: $("#port").val(),
|
||
username: $("#username").val(),
|
||
secret: $("#password").val(),
|
||
gameid: $("#gameid").val(),
|
||
rows: parseInt($("#terminalRow").val()),
|
||
columns: parseInt($("#terminalColumn").val()),
|
||
width: parseInt($("#terminalWidth").val()),
|
||
height: parseInt($("#terminalHeight").val()),
|
||
tab: $("#terminalTab").val(),
|
||
}
|
||
if (remember) {
|
||
store(options)
|
||
}
|
||
if (true) {
|
||
openTerminal(options)
|
||
} else {
|
||
for (var key in validResult) {
|
||
if (!validResult[key]) {
|
||
alert(errorMsg[key]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|