diff --git a/class/core/ssh_terminal.py b/class/core/ssh_terminal.py index 9dcdc590a..362d278f0 100644 --- a/class/core/ssh_terminal.py +++ b/class/core/ssh_terminal.py @@ -52,13 +52,18 @@ class ssh_terminal: __tp = None __ps = None + __ssh_list = {} + def __init__(self): - pass + ht = threading.Thread(target=self.heartbeat) + ht.start() + ht.join() def debug(self, msg): msg = "{} - {}:{} => {} \n".format(mw.formatDate(), self.__host, self.__port, msg) - # self.history_send(msg) + if not mw.isDebugMode(): + return mw.writeFile(self.__debug_file, msg, 'a+') def returnMsg(self, status, msg): @@ -193,10 +198,15 @@ class ssh_terminal: return self.returnMsg(False, "未知错误: {}".format(err)) self.debug('local-ssh:认证成功,正在构建会话通道') - self.__ssh = self.__ps.invoke_shell(term='xterm', width=83, height=21) - self.__ssh.setblocking(0) - self.__connect_time = time.time() - self.__last_send = [] + # self.__ssh = self.__ps.invoke_shell(term='xterm', width=83, height=21) + # self.__ssh.setblocking(0) + # self.__connect_time = time.time() + # self.__last_send = [] + + ssh = self.__ps.invoke_shell( + term='xterm', width=83, height=21) + ssh.setblocking(0) + self.__ssh_list[self.__sid] = ssh mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format( self.__host, self.__port)) self.debug('local-ssh:通道已构建') @@ -210,9 +220,6 @@ class ssh_terminal: if not self.__port: self.__port = 22 - if self.__host in ['127.0.0.1', 'localhost']: - self.__port = mw.getSSHPort() - self.setSshdConfig(True) num = 0 while num < 5: @@ -230,18 +237,16 @@ class ssh_terminal: if num == 5: self.setSshdConfig(True) self.debug('重试连接失败,{}'.format(e)) - if self.__host in ['127.0.0.1', 'localhost']: - return self.returnMsg(False, '连接目标服务器失败: {}'.format("Authentication failed ," + self.__user + "@" + self.__host + ":" + str(self.__port))) return self.returnMsg(False, '连接目标服务器失败, {}:{}'.format(self.__host, self.__port)) else: time.sleep(0.2) - # print(sock) + # print(self.__host, sock) self.__tp = paramiko.Transport(sock) try: self.__tp.start_client() self.__tp.banner_timeout = 60 - if not self.__pass or not self.__pkey: + if not self.__pass and not self.__pkey: return self.returnMsg(False, '密码或私钥不能都为空: {}:{}'.format(self.__host, self.__port)) if self.__pkey: @@ -313,11 +318,16 @@ class ssh_terminal: return self.returnMsg(False, "未知错误: {}".format(err)) self.debug('认证成功,正在构建会话通道') - self.__ssh = self.__tp.open_session() - self.__ssh.get_pty(term='xterm', width=100, height=34) - self.__ssh.invoke_shell() - self.__connect_time = time.time() - self.__last_send = [] + # self.__ssh = self.__tp.open_session() + # self.__ssh.get_pty(term='xterm', width=100, height=34) + # self.__ssh.invoke_shell() + # self.__connect_time = time.time() + # self.__last_send = [] + + ssh = self.__tp.open_session() + ssh.get_pty(term='xterm', width=100, height=34) + ssh.invoke_shell() + self.__ssh_list[self.__sid] = ssh mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format( self.__host, self.__port)) self.debug('通道已构建') @@ -326,6 +336,13 @@ class ssh_terminal: def setAttr(self, info): self.__host = info['host'].strip() + # 外部连接获取 + if not self.__host in ['127.0.0.1', 'localhost']: + dst_info = mw.getServerDir() + '/webssh/host/' + self.__host + '/info.json' + if os.path.exists(dst_info): + _t = mw.readFile(dst_info) + info = json.loads(_t) + if 'port' in info: self.__port = int(info['port']) if 'username' in info: @@ -336,8 +353,11 @@ class ssh_terminal: self.__pass = info['password'] if 'pkey_passwd' in info: self.__key_passwd = info['pkey_passwd'] + + print(self.__host, self.__pass, self.__key_passwd) try: result = self.connect() + print(result) except Exception as ex: if str(ex).find("NoneType") == -1: raise ex @@ -359,7 +379,8 @@ class ssh_terminal: def heartbeat(self): while True: - time.sleep(0.1) + time.sleep(1) + print("heartbeat:__ssh_list:", len(self.__ssh_list)) if self.__tp and self.__tp.is_active(): self.__tp.send_ignore() else: @@ -378,6 +399,7 @@ class ssh_terminal: 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无效') @@ -385,21 +407,27 @@ class ssh_terminal: if self.__connecting and not 'host' in info: return - if not self.__ssh: - self.__connecting = True - result = self.setAttr(info) - self.__connecting = False - else: + 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) - self.__ssh.send(info) - + if self.__ssh_list[sid].exit_status_ready(): + self.wsSend("已关闭!\r\n") + del(self.__ssh_list[sid]) + return + self.__ssh_list[sid].send(info) try: time.sleep(0.005) - recv = self.__ssh.recv(8192) + recv = self.__ssh_list[sid].recv(8192) return self.wsSend(recv) except Exception as ex: return self.wsSend('') diff --git a/plugins/webssh/js/webssh.js b/plugins/webssh/js/webssh.js index c71e3dfa4..3774609b4 100755 --- a/plugins/webssh/js/webssh.js +++ b/plugins/webssh/js/webssh.js @@ -154,7 +154,7 @@ function webShell_Load(){ } }); - webShell_Menu2(); + webShell_Menu(); } @@ -264,8 +264,9 @@ function webShell_getCmdList(){ } -function webShell_Menu2(){ +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] = new Terms_WebSocketIO('#'+random, { ssh_info: { host: "127.0.0.1", ps: "22", id: random } }); } diff --git a/route/__init__.py b/route/__init__.py index ff55188c4..62c188831 100755 --- a/route/__init__.py +++ b/route/__init__.py @@ -660,7 +660,7 @@ def webssh_websocketio(data): import ssh_terminal shell_client = ssh_terminal.ssh_terminal() - print("request.sid", request.sid) + # print("request.sid", request.sid) shell_client.run(request.sid, data) return diff --git a/route/static/js/term-websocketio.js b/route/static/js/term-websocketio.js index 517d3ce56..b9831b6bf 100644 --- a/route/static/js/term-websocketio.js +++ b/route/static/js/term-websocketio.js @@ -1,6 +1,4 @@ function Terms_WebSocketIO (el, config) { - - console.log(config); if (typeof config == "undefined") { config = {}; } @@ -17,9 +15,12 @@ function Terms_WebSocketIO (el, config) { this.run(); } -var socket, gterm; - Terms_WebSocketIO.prototype = { + + registerCloseCallBack:function(callback){ + this.callback_close = callback; + }, + // websocket持久化连接 connect: function (callback) { if(!this.ws){ @@ -29,64 +30,35 @@ Terms_WebSocketIO.prototype = { //连接服务器成功 on_open: function (ws_event) { - var http_token = $("#request_token_head").attr('token'); - this.ssh_info['x-http-token'] = http_token; - - this.send(JSON.stringify(this.ssh_info || { 'x-http-token': http_token })) this.term.FitAddon.fit(); this.resize({ cols: this.term.cols, rows: this.term.rows }); }, //服务器消息事件 on_message: function (ws_event) { - // console.log(ws_event.data); this.term.write(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(); + if (this.callback_close){ + this.callback_close(); + } } }, - //websocket关闭事件 on_close: function (ws_event) { this.ws = null; }, - //websocket错误事件 on_error: function (ws_event) { - if (ws_event.target.readyState === 3) { - // var msg = '错误: 无法创建WebSocket连接,请在面板设置页面关闭【开发者模式】'; - // layer.msg(msg,{time:5000}) - // if(Term.state === 3) return - // Term.term.write(msg) - // Term.state = 3; - } else { - console.log(ws_event) - } }, - //发送数据 - //@param event 唯一事件名称 - //@param data 发送的数据 - //@param callback 服务器返回结果时回调的函数,运行完后将被回收 + send: function (data, num) { - var that = this; - //如果没有连接,则尝试连接服务器 - if (!this.ws || this.bws.readyState == 3 || this.bws.readyState == 2) { - this.connect(); - } - //判断当前连接状态,如果!=1,则100ms后尝试重新发送 - if (this.ws.readyState === 1) { - this.ws.send(data); - } else { - if (this.state === 3) return; - if (!num) num = 0; - if (num < 5) { - num++; - setTimeout(function () { that.send(data, num++); }, 100) - } - } + }, //关闭连接 @@ -134,8 +106,7 @@ Terms_WebSocketIO.prototype = { this.term.on('data', function (data) { that.ws.emit('webssh_websocketio', data); }); - - // $('.terminal').detach().appendTo('#'+this.id); + this.ws.emit('webssh_websocketio', this.ssh_info); this.ws.emit('webssh_websocketio', '\n'); this.term.focus();