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;
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |