Hola colaboradores,
Estoy usando xtermjs para crear una aplicación de terminal que se ejecuta en un navegador web y el servidor de destino usa Linux. Me di cuenta de que xtermjs v4.9.0 no responde a ^ C cuando se ejecuta el comando yes
.
Luego hice una copia de seguridad a v4.0.2 y habilité la opción useFlowControl
, funcionó.
El useFlowControl
usando XON / XOFF se agregó desde v2.3.0 (PR # 447) pero se eliminó de v4.1.0 (PR # 2422).
No encuentro ninguna discusión sobre el motivo para eliminarlo. ¿Tiene la solución XON / XOFF algún problema?
Si no es así, ¿podemos tener un plan para traer de vuelta esta función a la biblioteca o debería implementarla en mi propia aplicación?
El control de flujo descrito en el documento (https://xtermjs.org/docs/guides/flowcontrol/) no ayuda mucho ya que uso websocket para conectarme al backend.
Eliminamos XON / XOFF porque no funcionó de manera confiable en algunos escenarios. Desde el fondo de mi cabeza, recuerdo que tuvimos problemas con el shell ZSH, que usaba las secuencias XON / XOFF para algo diferente. Creo que la Terminal de Windows también tuvo problemas con estas secuencias.
De todos modos, la forma en que resolví esto (también usando WebSockets, en mi caso socket.io pero no importa) es establecer manualmente un mecanismo de control de flujo sobre el propio socket.
Entonces, cada vez que llegan datos al socket que deben escribirse en xterm.js, aumentamos un contador, y una vez que los datos se escribieron con éxito en xterm.js (lo que significa que xterm.js los procesó), disminuimos ese contador .
Si el contador excede un cierto umbral, enviamos un mensaje pause
través de Websocket, que en el lado del servidor pausará el flujo de pty ( terminalStream.pause()
). Una vez que bajamos de ese umbral, enviamos un mensaje resume
través de Websocket, que en el lado del servidor reanudará el flujo pty ( terminalStream.resume()
).
Tenga en cuenta que los métodos terminalStream.pause()
y terminalStream.resume()
son los métodos de Stream incorporados de node.js para manejar la contrapresión. node-pty
y ssh2
soportan el manejo de la contrapresión a través de estos métodos.
// client
const MAX_PENDING_WRITES = 5;
let pendingWrites = 0;
let paused = false;
socket.on('data', (data) => {
pendingWrites++;
xterm.write(data, () => {
pendingWrites--;
if (pendingWrites > MAX_PENDING_WRITES && !paused) {
paused = true;
socket.emit('pause');
return;
}
if (pendingWrites <= MAX_PENDING_WRITES && paused) {
paused = false;
socket.emit('resume');
return;
}
});
});
// server
terminalStream.on('data', (data) => socket.emit('data', data);
socket.on('data', (data) => terminalStream.write(data));
socket.on('pause', () => terminalStream.pause();
socket.on('resume', () => terminalStream.resume();
Este mecanismo está funcionando bastante confiable hasta ahora. El comando yes
ya no inundará la conexión. Todavía hay un retraso de aproximadamente 0,5 segundos entre CTRL+C
y la terminación real del comando en escenarios de alto rendimiento, pero en mi opinión eso está bien.
Espero que ayude.
@tandatle Consulte también la documentación sobre flowcontrol .
Editar: Lo siento, pasé por alto su comentario de documentos. ¿Te importaría explicar lo que no está claro allí? Sí, la sección de websocket es solo un código auxiliar (no un fragmento listo para usar), ya que no hice qué crear toneladas de fragmentos para diferentes bibliotecas de sockets y necesidades personalizadas (esto es difícil de hacer bien con websockets solo por razones de seguridad) . Aún así, siéntase libre de agregar un fragmento concreto que cubra esos aspectos.
@mofux @jerch Gracias por su ayuda.
No estoy usando node.js en el backend, sino un proceso escrito en C ++, por lo que es posible que tenga que hacer algunas investigaciones más para elegir entre usar XON / XOFF e implementar el manejo de backpresure en mi proceso de backend.
Muchas gracias.
Comentario más útil
Eliminamos XON / XOFF porque no funcionó de manera confiable en algunos escenarios. Desde el fondo de mi cabeza, recuerdo que tuvimos problemas con el shell ZSH, que usaba las secuencias XON / XOFF para algo diferente. Creo que la Terminal de Windows también tuvo problemas con estas secuencias.
De todos modos, la forma en que resolví esto (también usando WebSockets, en mi caso socket.io pero no importa) es establecer manualmente un mecanismo de control de flujo sobre el propio socket.
Entonces, cada vez que llegan datos al socket que deben escribirse en xterm.js, aumentamos un contador, y una vez que los datos se escribieron con éxito en xterm.js (lo que significa que xterm.js los procesó), disminuimos ese contador .
Si el contador excede un cierto umbral, enviamos un mensaje
pause
través de Websocket, que en el lado del servidor pausará el flujo de pty (terminalStream.pause()
). Una vez que bajamos de ese umbral, enviamos un mensajeresume
través de Websocket, que en el lado del servidor reanudará el flujo pty (terminalStream.resume()
).Tenga en cuenta que los métodos
terminalStream.pause()
yterminalStream.resume()
son los métodos de Stream incorporados de node.js para manejar la contrapresión.node-pty
yssh2
soportan el manejo de la contrapresión a través de estos métodos.Este mecanismo está funcionando bastante confiable hasta ahora. El comando
yes
ya no inundará la conexión. Todavía hay un retraso de aproximadamente 0,5 segundos entreCTRL+C
y la terminación real del comando en escenarios de alto rendimiento, pero en mi opinión eso está bien.Espero que ayude.