Xterm js + pty + websocket странные символы после переподключения
Я пишу веб-терминал для удовольствия. Я использую xterm js + pty. У меня есть сервер Linux, и клиент использует веб-сокет для подключения к нему. Веб-сокет отправит сообщение на сервер, которое будет отправлено на терминал, созданный 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", любое последующее переподключение приведет к тому, что в конце появятся странные символы.
Я много гуглил, но не нашел много. Единственное, что я нашел здесь, это похоже на кучу сообщений об ошибках от termcap.
Последующие действия: я обнаружил, что проблема на самом деле была из xterm js на стороне клиента. Вот что я сделал:
Я добавил console.log в аддон xterm js attach, чтобы проверить, отправляет ли эти символы сначала сервер xterm js после переподключения. И оказалось "да". Смотрите в журнале консоли.
После открытия vim я отключил интернет. И этот журнал появился сразу после переподключения. Как видите, терминал (объект терминала xterm js) сначала отправляет в сокет эти символы и получает обратно с сервера через сокет с тем же самым действием. Я искал кодовую базу xterm js, похоже, эти символы генерируются из https://github.com/sourcelair/xterm.js/blob/42724c7f42f827d9e247d461066eb1506725e371/src/Parser.ts#L526-L535.
Любая идея?