diff --git a/webssh/settings.py b/webssh/settings.py index 281a8b5..f03b4b3 100644 --- a/webssh/settings.py +++ b/webssh/settings.py @@ -45,7 +45,7 @@ define('origin', default='same', help='''Origin policy, '': custom domains policy, matches any domain in the list separated by comma; '*': wildcard policy, matches any domain, allowed in debug mode only.''') -define('wpintvl', type=float, default=0, help='Websocket ping interval') +define('wpintvl', type=float, default=30, help='Websocket ping interval') define('timeout', type=float, default=3, help='SSH connection timeout') define('delay', type=float, default=3, help='The delay to call recycle_worker') define('maxconn', type=int, default=20, diff --git a/webssh/static/js/main.js b/webssh/static/js/main.js index 5d40e9c..58daf92 100644 --- a/webssh/static/js/main.js +++ b/webssh/static/js/main.js @@ -52,6 +52,7 @@ jQuery(function($){ debug = document.querySelector(form_id).noValidate, custom_font = document.fonts ? document.fonts.values().next().value : undefined, default_fonts, + current_terminal, DISCONNECTED = 0, CONNECTING = 1, CONNECTED = 2, @@ -475,9 +476,40 @@ jQuery(function($){ } + function clear_terminal() { + if (current_terminal) { + try { + current_terminal.dispose(); + } catch (e) { + console.error(e); + } + current_terminal = undefined; + } + $('#terminal').removeClass('terminal-fullscreen').empty(); + } + + + function write_disconnect_message(term, reason) { + var text = translate_status(reason) || '连接已断开。'; + + if (term) { + try { + term.write('\r\n\r\n\x1b[33m' + text + '\x1b[0m\r\n'); + term.setOption('disableStdin', true); + } catch (e) { + console.error(e); + } + } + + return text; + } + + function log_status(text, to_populate) { text = translate_status(text); - console.log(text); + if (text) { + console.log(text); + } status.text(text); if (to_populate && validated_form_data) { @@ -510,7 +542,17 @@ jQuery(function($){ ['Missing value username', '请输入 SSH 用户名。'], ['Missing argument hostname', '缺少主机地址。'], ['Missing argument username', '缺少 SSH 用户名。'], - ['Need a verification code for 2fa.', '需要输入动态验证码。'] + ['Need a verification code for 2fa.', '需要输入动态验证码。'], + ['Login required.', '登录状态已失效,请重新登录。'], + ['Websocket authentication failed.', 'WebSocket 认证失败。'], + ['websocket closed', 'WebSocket 连接已关闭。'], + ['client disconnected', '客户端连接已断开。'], + ['chan closed', 'SSH 会话已关闭。'], + ['chan error on reading', '读取 SSH 会话时连接中断。'], + ['chan error on writing', '写入 SSH 会话时连接中断。'], + ['worker recycled', '连接等待超时,已被回收。'], + ['Worker closed', 'SSH 工作连接已关闭。'], + ['No worker found', '未找到活动的 SSH 连接。'] ]; var i, item; @@ -581,7 +623,9 @@ jQuery(function($){ } } + clear_terminal(); var term = new window.Terminal(termOptions); + current_terminal = term; term.fitAddon = new window.FitAddon.FitAddon(); term.loadAddon(term.fitAddon); @@ -749,11 +793,13 @@ jQuery(function($){ }; sock.onclose = function(e) { - term.dispose(); - term = undefined; + var reason = write_disconnect_message(term, e.reason); + + $('#terminal').removeClass('terminal-fullscreen'); sock = undefined; reset_wssh(); - log_status(e.reason, true); + log_status(reason, true); + term = undefined; state = DISCONNECTED; default_title = 'WebSSH'; title_element.text = default_title;