diff --git a/class/core/ssh_terminal.py b/class/core/ssh_terminal.py index a6272ec61..67cd66228 100644 --- a/class/core/ssh_terminal.py +++ b/class/core/ssh_terminal.py @@ -53,12 +53,11 @@ class ssh_terminal: __ps = None __ssh_list = {} + __ssh_last_request_time = {} def __init__(self): - # ht = threading.Thread(target=self.heartbeat) - # ht.start() - # ht.join() - pass + ht = threading.Thread(target=self.heartbeat) + ht.start() def debug(self, msg): msg = "{} - {}:{} => {} \n".format(mw.formatDate(), @@ -208,6 +207,7 @@ class ssh_terminal: term='xterm', width=83, height=21) ssh.setblocking(0) self.__ssh_list[self.__sid] = ssh + self.__ssh_last_request_time[self.__sid] = time.time() mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format( self.__host, self.__port)) self.debug('local-ssh:通道已构建') @@ -329,6 +329,7 @@ class ssh_terminal: ssh.get_pty(term='xterm', width=100, height=34) ssh.invoke_shell() self.__ssh_list[self.__sid] = ssh + self.__ssh_last_request_time[self.__sid] = time.time() mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format( self.__host, self.__port)) self.debug('通道已构建') @@ -355,10 +356,10 @@ class ssh_terminal: if 'pkey_passwd' in info: self.__key_passwd = info['pkey_passwd'] - print(self.__host, self.__pass, self.__key_passwd) + # print(self.__host, self.__pass, self.__key_passwd) try: result = self.connect() - print(result) + # print(result) except Exception as ex: if str(ex).find("NoneType") == -1: raise ex @@ -378,16 +379,13 @@ class ssh_terminal: except: pass - def heartbeat(self): - while True: - time.sleep(3) - print("heartbeat:__ssh_list:", len(self.__ssh_list)) - # self.debug("heartbeat:__ssh_list:" + str(len(self.__ssh_list))) - # if self.__tp and self.__tp.is_active(): - # self.__tp.send_ignore() - - # if self.__ps and self.__ps.is_active(): - # self.__ps.send_ignore() + def resize(self, data): + try: + self.__ssh_list[self.__sid].resize_pty( + width=data['cols'], height=data['rows']) + return True + except: + return False def wsSend(self, recv): try: @@ -396,42 +394,6 @@ class ssh_terminal: except Exception as e: return emit('server_response', {'data': recv}) - def run(self, sid, info): - # sid = mw.md5(sid) - self.__sid = sid - if not self.__sid: - return self.wsSend('WebSocketIO无效') - - if self.__connecting and not 'host' in info: - return - - result = self.returnMsg(False, '') - if not sid in self.__ssh_list: - if type(info) == dict: - self.__connecting = True - result = self.setAttr(info) - self.__connecting = False - - if sid in self.__ssh_list: - result = self.returnMsg(True, '已连接') - - if result['status']: - if type(info) == str: - time.sleep(0.1) - if self.__ssh_list[sid].exit_status_ready(): - self.wsSend("logout\r\n") - del(self.__ssh_list[sid]) - return - self.__ssh_list[sid].send(info) - try: - time.sleep(0.005) - recv = self.__ssh_list[sid].recv(8192) - return self.wsSend(recv) - except Exception as ex: - return self.wsSend('') - else: - return self.wsSend(result['msg']) - def getSshDir(self): if mw.isAppleSystem(): user = mw.execShell( @@ -470,3 +432,62 @@ class ssh_terminal: mw.execShell(cmd) cmd = 'chmod 600 ' + ssh_dir + '/authorized_keys' mw.execShell(cmd) + + def heartbeat(self): + while True: + time.sleep(3) + + cur_time = time.time() + print("heartbeat:cur_time:", cur_time) + print("heartbeat:__ssh_list:", len(self.__ssh_list)) + for x in self.__ssh_list: + ssh_last_time = self.__ssh_last_request_time[x] + print(x, self.__ssh_list[x]) + # self.debug("heartbeat:__ssh_list:" + str(len(self.__ssh_list))) + # if self.__tp and self.__tp.is_active(): + # self.__tp.send_ignore() + + # if self.__ps and self.__ps.is_active(): + # self.__ps.send_ignore() + + def run(self, sid, info): + # sid = mw.md5(sid) + self.__sid = sid + if not self.__sid: + return self.wsSend('WebSocketIO无效') + + if self.__connecting and not 'host' in info: + return + + result = self.returnMsg(False, '') + if not sid in self.__ssh_list: + if type(info) == dict and 'host' in info: + self.__connecting = True + result = self.setAttr(info) + self.__connecting = False + + if sid in self.__ssh_list: + if 'resize' in info: + self.resize(info) + result = self.returnMsg(True, '已连接') + + print("req.__ssh_list:", str(len(self.__ssh_list))) + print("req.:cmd:", sid, info) + if result['status']: + if type(info) == str: + time.sleep(0.1) + cur_ssh = self.__ssh_list[sid] + if cur_ssh.exit_status_ready(): + self.wsSend("logout\r\n") + del(self.__ssh_list[sid]) + return + + cur_ssh.send(info) + try: + time.sleep(0.005) + recv = cur_ssh.recv(8192) + return self.wsSend(recv) + except Exception as ex: + return self.wsSend('') + else: + return self.wsSend(result['msg']) diff --git a/plugins/webssh/js/webssh.js b/plugins/webssh/js/webssh.js index 4c1e05872..43349f32e 100755 --- a/plugins/webssh/js/webssh.js +++ b/plugins/webssh/js/webssh.js @@ -2,6 +2,14 @@ //全局 var host_ssh_list = []; +//刷新页面 +$(window).unload(function(){ + for (i in host_ssh_list) { + host_ssh_list[i].close(); + } + return false; +}); + function appPost(method,args,callback){ var _args = null; if (typeof(args) == 'string'){ @@ -68,10 +76,20 @@ $(document).ready(function(){ } }); +function webShell_Resize(){ + var cur_ssh = $('.term_item_tab .list .active'); + var data = $(cur_ssh).data(); + var item = host_ssh_list[data.id]; + item.term.focus(); + item.term.fit(); + item.resize({ cols: item.term.cols, rows: item.term.rows}); +} + function webShell_Load(){ changeDivH(); $(window).resize(function(){ changeDivH(); + webShell_Resize(); }); $('.term_content_tab .term-tool-button').click(function(){ @@ -86,8 +104,11 @@ function webShell_Load(){ $(this).removeClass('tool-hide').addClass('tool-show'); $(this).find('span').removeClass('glyphicon-menu-right').addClass('glyphicon-menu-left'); } + webShell_Resize(); }); + + $('.full_exit_screen').click(function(ele){ if($(this).hasClass('glyphicon-resize-full')){ requestFullScreen($('#term_box_view')[0]); @@ -112,16 +133,14 @@ function webShell_Load(){ // 切换服务器终端视图 $('.term_item_tab .list').on('click', 'span.item', function (ev) { - var index = $(this).index(), data = $(this).data(); + var index = $(this).index(); + var data = $(this).data(); if ($(this).hasClass('addServer')) { } else if ($(this).hasClass('tab_tootls')) { } else { $(this).addClass('active').siblings().removeClass('active'); $('.term_content_tab .term_item:eq(' + index + ')').addClass('active').siblings().removeClass('active'); - var item = host_ssh_list[data.id]; - // item.term.focus(); - // item.term.FitAddon.fit(); - // item.resize({ cols: item.term.cols, rows: item.term.rows }); + webShell_Resize(); } }); @@ -155,6 +174,8 @@ function webShell_Load(){ }); webShell_Menu(); + // webShell_Resize(); + // $('.term_content_tab .term-tool-button').click(); } @@ -277,11 +298,9 @@ function webShell_Menu(){ var random = 'localhost'; // host_ssh_list[random] = new Terms_WebSocketIO('#'+random, { ssh_info: { host: "38.6.224.67", ps: "22", id: random } }); host_ssh_list[random] = Terms_WebSocketIO_Create('127.0.0.1',random); - } function webShell_openTermView(info) { - console.log(info); if (typeof info === "undefined") { info = { host: '127.0.0.1', ps: '本地服务器' } } @@ -296,6 +315,8 @@ function webShell_openTermView(info) { } item_list.append('
' + info.ps + '
'); host_ssh_list[random] = Terms_WebSocketIO_Create(info.host, random); + + webShell_Resize(); } @@ -308,6 +329,7 @@ function webShell_removeTermView(id){ try { host_ssh_list[id].close(); } catch (error) { + console.log(error); } delete host_ssh_list[id]; diff --git a/plugins/webssh/menu/index.css b/plugins/webssh/menu/index.css index 249c427b7..c90814271 100644 --- a/plugins/webssh/menu/index.css +++ b/plugins/webssh/menu/index.css @@ -310,27 +310,29 @@ color: #bbb; color: #4c4c4c; } -.term_content_tab .term_item { - height: 100%; - width: 100%; - display: none; -} -.term_content_tab .term_item.active { - display: inline-block; -} .term_content_tab { - background-color: #000; + background-color: rgb(51, 51, 51); position: absolute; top: 38px; left: 0; right: 0; bottom: 0; - padding: 10px 5px 10px 10px; + padding: 10px 10px 10px 10px; overflow: hidden; } +.term_content_tab .term_item { + height: 100%; + width: 100%; + display: none; +} + +.term_content_tab .term_item.active { + display: inline-block; +} + .term-tool-button { position: absolute; right: -7px; diff --git a/plugins/webssh/menu/index.html b/plugins/webssh/menu/index.html index f7f8a4958..2ef622f5e 100755 --- a/plugins/webssh/menu/index.html +++ b/plugins/webssh/menu/index.html @@ -9,7 +9,10 @@
-
本地服务器
+
+ 本地服务器 +
+
@@ -23,7 +26,7 @@
-
+
diff --git a/route/static/js/term-websocketio.js b/route/static/js/term-websocketio.js index cd2d6372f..482503fb2 100644 --- a/route/static/js/term-websocketio.js +++ b/route/static/js/term-websocketio.js @@ -23,80 +23,91 @@ Terms_WebSocketIO.prototype = { this.callback_close = callback; }, - // websocket持久化连接 - connect: function (callback) { + connectWs: function (callback) { if(!this.ws){ this.ws = io.connect(); } }, - //连接服务器成功 - on_open: function (ws_event) { - this.term.FitAddon.fit(); - this.resize({ cols: this.term.cols, rows: this.term.rows }); + connectSsh:function(){ + this.send(this.ssh_info); + this.send('\n'); + }, + + close:function(){ + this.ws.disconnect(); + this.ws.close(); }, - //服务器消息事件 on_message: function (ws_event) { this.term.write(ws_event.data); + console.log(ws_event.data); if (ws_event.data == '\r\n登出\r\n' || ws_event.data == '登出\r\n' || ws_event.data == '\r\nlogout\r\n' || ws_event.data == 'logout\r\n'|| ws_event.data == '\r\nexit\r\n' || ws_event.data == 'exit\r\n') { this.term.destroy(); - clearInterval(this.term_timer); this.ws.disconnect(); this.ws.close(); + clearInterval(this.term_timer); - console.log('message',this.callback_close,typeof(this.callback_close)); if (this.callback_close){ this.callback_close(); } } }, - resize: function (size) { - if (this.ws) { - size['resize'] = 1; - this.send(JSON.stringify(size)); - } + + on_connect:function(ws_event){ + + }, + + on_exit:function(ws_event){ + + }, + + send:function(data){ + this.ws.emit(this.route, data); + }, + + resize: function (size) { + if (this.ws) { + size['resize'] = 1; + this.send(size) + } }, run: function (ssh_info) { - this.connect(); + this.connectWs(); var that = this; var termCols = 83; var termRows = 21; - this.term = new Terminal({ cols: termCols, rows: termRows, screenKeys: true, useStyle: true}); + this.term = new Terminal({fontSize: this.fontSize,screenKeys: true, useStyle: true}); this.term.open($('#'+this.id)[0]); this.term.setOption('cursorBlink', true); - this.term.setOption('fontSize', this.fontSize); - - // console.log(this.term.cols,this.term.rows); - // this.term.fit(); - // console.log(this.term.cols,this.term.rows); - - // this.term.FitAddon = new window.FitAddon(); - // this.term.loadAddon(this.term.FitAddon); - // this.term.WebLinksAddon = new WebLinksAddon.WebLinksAddon(); - // this.term.loadAddon(this.term.WebLinksAddon); - this.ws.on('server_response', function (ev) { that.on_message(ev)}); + this.ws.on('connect', function (ev) { that.on_connect(ev)}); + this.ws.on('exit', function (ev) { that.on_exit(ev)}); if (this.ws) { - that.ws.emit('webssh_websocketio', ''); + that.send(''); this.term_timer = setInterval(function () { - that.ws.emit('webssh_websocketio', ''); - }, 500); + that.send(''); + }, 600); } this.term.on('data', function (data) { - that.ws.emit('webssh_websocketio', data); + try { + that.send(data) + } catch (e) { + that.term.write('\r\n连接丢失,正在尝试重新连接!\r\n'); + that.connectSsh(); + } }); - - this.ws.emit('webssh_websocketio', this.ssh_info); - this.ws.emit('webssh_websocketio', '\n'); + that.term.write('\r\n请稍等,正在链接中...\r\n'); + + this.connectSsh(); this.term.focus(); } }