我正在写一个网络终端来玩。我正在使用 xterm js + pty。我有一个 linux 服务器,客户端使用 websocket 连接到它。websocket 将向服务器发送消息,该消息将发送到由 pty 生成的终端。任何输出都将通过 websocket 发送回 xterm 中的客户端。一切正常。
但是在不稳定的网络中,我想在断开连接后重新连接websocket。这是我的处理方式。
function createWebSocket() {
var socket = new WebSocket(socketUri);
socket.onopen = handleSocketOpen;
socket.onclose = handleSocketClose;
}
function handleSocketClose() {
term.writeln("\n\r\x1B[1;31mTerminal was disconnected.\x1B[0m ");
retryConnectClosedSocketOrCleanup(1);
}
function retryConnectClosedSocketOrCleanup(retryCount) {
// Get current term size.
var method = 'POST';
var geometry = term.proposeGeometry();
var targetUri = consoleUri + '/terminals/' + termId + '/size?cols=' + geometry.cols + '&rows=' + geometry.rows;
// Resize terminal to detect if the terminal exists on the server.
$.ajax(targetUri,
{
method: method,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
timeout: 3000
})
.fail(function (jqXHR, textStatus, errorThrown) {
// If resize failed with 4xx or 5xx, then there is no way to reconnect to the same terminal.
// Do socket close clean up right away.
if (jqXHR.status >= 400) {
console.warn("Terminal failed to reconnect because the previous session no longer exists.");
socketCloseCleanup();
return;
}
// If resize failed with other reason, retry.
retryCount = retryCount || 0;
if (retryCount > maxRetrySocketConnectionCount) {
term.writeln("\n\r\x1B[1;31mTerminal failed to reconnect after " + maxRetrySocketConnectionCount + " attempts. \x1B[0m");
socketCloseCleanup();
} else {
term.write(retryCount == 1 ? "\n\r\x1B[1;31mReconnecting terminal.." : "\x1B[1;31m.");
setTimeout(function () { retryConnectClosedSocketOrCleanup(retryCount + 1) }, retrySocketConnectionDelay);
}
})
.done(function (data, textStatus, jqXHR) {
// If resize was successful, then the terminal still exists on the server.
// Reopen socket.
if (jqXHR.status === 200) {
term.writeln("\x1B[1;32m Terminal reconnected.\x1B[0m ");
term.fit();
term.clear();
term.eraseLine(0);
createWebSocket();
}
});
}
在大多数情况下它也可以正常工作。但是,一旦我使用“vi”或“vim”,任何后续的重新连接都会导致最后出现一些奇怪的字符。
我用谷歌搜索了很多,但没有找到太多。我唯一发现的是here,它看起来像是来自termcap 的一堆错误响应。
跟进: 我发现问题实际上来自客户端的 xterm js。这是我所做的:
我将 console.log 添加到 xterm js attach 插件,以查看是否是 xterm js 在重新连接后首先将这些字符发送到服务器。结果是“是的”。请参阅控制台日志。
打开vim后,我断开了互联网。此日志在重新连接后立即出现。如您所见,终端(xterm js Terminal 对象)首先使用这些字符发送到套接字,然后通过套接字从服务器接收到相同的内容。我搜索了 xterm js 的代码库,看起来这些字符是从https://github.com/sourcelair/xterm.js/blob/42724c7f42f827d9e247d461066eb1506725e371/src/Parser.ts#L526-L535生成的。
任何想法?