Hallo Mitwirkende,
Ich verwende xtermjs, um eine Terminalanwendung zu erstellen, die im Webbrowser ausgeführt wird, und der Zielserver verwendet Linux. Ich habe festgestellt, dass xtermjs v4.9.0 nicht auf ^ C reagiert, wenn der Befehl yes
ausgeführt wird.
Dann habe ich auf v4.0.2 zurückgesetzt und die Option useFlowControl
aktiviert, es hat funktioniert.
Das useFlowControl
mit XON / XOFF wurde aus Version 2.3.0 (PR # 447) hinzugefügt, aber aus Version 4.1.0 (PR # 2422) entfernt.
Ich kann keine Diskussion über den Grund finden, es zu entfernen. Hat die XON / XOFF-Lösung eine Gefahr?
Wenn nicht, können wir einen Plan haben, um diese Funktion wieder in die Bibliothek zu bringen, oder sollte ich sie in meiner eigenen Anwendung implementieren?
Die im Dokument beschriebene Flusskontrolle (https://xtermjs.org/docs/guides/flowcontrol/) hilft nicht viel, da ich Websocket verwende, um eine Verbindung zum Backend herzustellen.
Wir haben XON / XOFF entfernt, da es in einigen Szenarien nicht zuverlässig funktionierte. Aus dem Hinterkopf erinnere ich mich, dass wir Probleme mit der ZSH-Shell hatten, die die XON / XOFF-Sequenzen für etwas anderes verwendete. Ich glaube, das Windows-Terminal hatte auch Probleme mit diesen Sequenzen.
Wie auch immer - die Art und Weise, wie ich dies gelöst habe (auch mit WebSockets - in meinem Fall socket.io, aber es spielt keine Rolle), besteht darin, manuell einen Flusskontrollmechanismus über den Socket selbst einzurichten.
Wenn also Daten auf dem Socket eintreffen, die in xterm.js geschrieben werden sollen, erhöhen wir einen Zähler. Sobald die Daten erfolgreich in xterm.js geschrieben wurden (was bedeutet, dass sie von xterm.js gerendert wurden), verringern wir diesen Zähler .
Wenn der Zähler einen bestimmten Schwellenwert überschreitet, senden wir eine pause
-Nachricht über das Websocket, die auf der Serverseite den Pty-Stream pausiert ( terminalStream.pause()
). Sobald wir diesen Schwellenwert unterschreiten, senden wir eine resume
-Nachricht über das Websocket, die auf der Serverseite den Pty-Stream wieder aufnimmt ( terminalStream.resume()
).
Beachten Sie, dass die Methoden terminalStream.pause()
und terminalStream.resume()
die integrierten Node.js-Stream-Methoden zur Behandlung des Gegendrucks sind. node-pty
sowie ssh2
unterstützen die Behandlung des Gegendrucks über diese Methoden.
// 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();
Dieser Mechanismus funktioniert bisher ziemlich zuverlässig. Der Befehl yes
überflutet die Verbindung nicht mehr. Es gibt immer noch eine Verzögerung von ungefähr 0,5 Sekunden zwischen CTRL+C
und der tatsächlichen Beendigung des Befehls in Szenarien mit hohem Durchsatz, aber IMO ist das in Ordnung.
Ich hoffe, es hilft.
@tandatle Siehe auch die Dokumente zur Flusskontrolle .
Bearbeiten: Entschuldigung, übersehen Sie Ihre Docs Bemerkung. Möchtest du erklären, was dort unklar ist? Ja, der Websocket-Bereich ist nur ein Stub (kein sofort einsatzbereites Snippet), da ich nicht getan habe, um Tonnen von Snippets für verschiedene Socket-Bibliotheken und benutzerdefinierte Anforderungen zu erstellen (dies ist allein aus Sicherheitsgründen mit Websockets nur schwer richtig zu machen). . Sie können immer noch einen konkreten Ausschnitt hinzufügen, der diese Aspekte abdeckt.
@mofux @jerch Danke für deine Hilfe.
Ich verwende nicht node.js im Backend, sondern einen in C ++ geschriebenen Prozess. Daher muss ich möglicherweise weitere Untersuchungen durchführen, um zwischen der Verwendung von XON / XOFF und der Implementierung der Backpresure-Behandlung in meinem Backend-Prozess zu wählen.
Ich danke dir sehr.
Hilfreichster Kommentar
Wir haben XON / XOFF entfernt, da es in einigen Szenarien nicht zuverlässig funktionierte. Aus dem Hinterkopf erinnere ich mich, dass wir Probleme mit der ZSH-Shell hatten, die die XON / XOFF-Sequenzen für etwas anderes verwendete. Ich glaube, das Windows-Terminal hatte auch Probleme mit diesen Sequenzen.
Wie auch immer - die Art und Weise, wie ich dies gelöst habe (auch mit WebSockets - in meinem Fall socket.io, aber es spielt keine Rolle), besteht darin, manuell einen Flusskontrollmechanismus über den Socket selbst einzurichten.
Wenn also Daten auf dem Socket eintreffen, die in xterm.js geschrieben werden sollen, erhöhen wir einen Zähler. Sobald die Daten erfolgreich in xterm.js geschrieben wurden (was bedeutet, dass sie von xterm.js gerendert wurden), verringern wir diesen Zähler .
Wenn der Zähler einen bestimmten Schwellenwert überschreitet, senden wir eine
pause
-Nachricht über das Websocket, die auf der Serverseite den Pty-Stream pausiert (terminalStream.pause()
). Sobald wir diesen Schwellenwert unterschreiten, senden wir eineresume
-Nachricht über das Websocket, die auf der Serverseite den Pty-Stream wieder aufnimmt (terminalStream.resume()
).Beachten Sie, dass die Methoden
terminalStream.pause()
undterminalStream.resume()
die integrierten Node.js-Stream-Methoden zur Behandlung des Gegendrucks sind.node-pty
sowiessh2
unterstützen die Behandlung des Gegendrucks über diese Methoden.Dieser Mechanismus funktioniert bisher ziemlich zuverlässig. Der Befehl
yes
überflutet die Verbindung nicht mehr. Es gibt immer noch eine Verzögerung von ungefähr 0,5 Sekunden zwischenCTRL+C
und der tatsächlichen Beendigung des Befehls in Szenarien mit hohem Durchsatz, aber IMO ist das in Ordnung.Ich hoffe, es hilft.