Die IOCP- (Windows) und EPOLL- (Linux) Server-Engines in sgcWebSockets verarbeiten Tausende von Verbindungen mit einem kleinen Thread-Pool statt einem Thread pro Verbindung, und genau das macht sie zur richtigen Wahl für Server unter hoher gleichzeitiger Last. Bisher konnten sie jedoch nicht bemerken, wenn eine Gegenstelle verstummt, ohne sich zu verabschieden. Zwei neue Optionen, TCPKeepAlive und KeepAliveTimeout, schließen diese Lücke.
Eine stille Gegenstelle erzeugt nie ein Ereignis
IOCP und EPOLL sind ereignisgesteuert: Die Engine schläft, bis das Betriebssystem ihr mitteilt, dass ein Socket Daten hat, geschlossen wurde oder einen Fehler aufweist. Das funktioniert gut, bis eine Gegenstelle verschwindet, ohne ein sauberes FIN oder RST zu senden, zum Beispiel weil ein Client abstürzt, eine NAT- oder Firewall-Zuordnung für eine inaktive Verbindung verworfen wird oder sich eine Route stillschweigend ändert. Für diesen Socket trifft nie ein Ereignis ein, sodass die Verbindung auf dem Server unbegrenzt ESTABLISHED bleibt.
Der klassische Thread-pro-Verbindung-IOHandler hat dieses Problem nicht, da jede Verbindung bei einem Lesevorgang mit Timeout blockiert, sodass eine stille Verbindung beim nächsten Ablauf dieses Timeouts erkannt und freigegeben wird. IOCP und EPOLL hatten dafür keinen gleichwertigen Mechanismus, und genau das fügen diese beiden neuen Optionen hinzu.
TCPKeepAlive: Das Betriebssystem übernimmt die Überwachung
Aktivieren Sie TCPKeepAlive, und das Betriebssystem selbst beginnt, eine Verbindung zu prüfen, sobald sie Time Sekunden lang inaktiv war, und wiederholt dies alle Interval Sekunden, bis die Gegenstelle antwortet oder die Verbindung getrennt wird. Die Option ist standardmäßig deaktiviert; die folgenden Werte entsprechen den Standardwerten, wenn sie aktiviert ist.
Server.IOHandlerOptions.IOHandlerType := iohEPOLL;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Enabled := True;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Time := 60; // seconds idle before probing
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Interval := 10; // seconds between probes
Auf einem Windows-Server befinden sich dieselben drei Eigenschaften unter IOHandlerOptions.IOCP.TCPKeepAlive.
KeepAliveTimeout: Ein Idle-Timeout auf Anwendungsebene
KeepAliveTimeout verfolgt einen anderen, direkteren Ansatz: Es schließt jede Verbindung, die länger als die angegebene Anzahl an Sekunden inaktiv war, unabhängig davon, was die Keepalive-Prüfungen des Betriebssystems ergeben. Das kommt der Art, wie der Thread-pro-Verbindung-IOHandler eine stille Verbindung bereits freigibt, am nächsten, ist standardmäßig deaktiviert (ein Wert von 0), und es betrifft nur wirklich inaktive Verbindungen, eine Anfrage, die gerade gelesen wird, oder eine Antwort, die gerade geschrieben wird, wird davon nie unterbrochen.
Server.IOHandlerOptions.EPOLL.KeepAliveTimeout := 120; // seconds
// Windows
Server.IOHandlerOptions.IOCP.KeepAliveTimeout := 120;
Setzen Sie den Wert komfortabel über Ihrer langsamsten erwarteten Anfrage oder Antwort, zum Beispiel 120 Sekunden für einen typischen HTTP- oder WebSocket-Server, damit wirklich tote Verbindungen zügig entfernt werden, ohne jemals eine nur langsame Verbindung zu treffen.
Ein dritter Weg, eine Trennung zu erkennen
sgcWebSockets bot bereits zwei Möglichkeiten, das Verschwinden einer Gegenstelle zu bemerken: die Aktivierung von CleanDisconnect bei TsgcWebSocketClient, sodass ein wohlerzogener Client den Server informiert, bevor er verschwindet, oder ein serverseitiger heartbeat, der jeden Client in einem Intervall anpingt. Beide hängen von Kooperation ab, im ersten Fall vom Client, im zweiten Fall vom eigenen Ping/Pong-Umlauf. TCPKeepAlive und KeepAliveTimeout sind die erste Option, die nichts davon benötigt: Der Server erkennt eine tote Verbindung vollständig eigenständig.
Verfügbarkeit
Beide Optionen sind ab sofort in sgcWebSockets für Delphi und C++ Builder 7 bis 13 verfügbar, unter IOHandlerOptions.EPOLL und IOHandlerOptions.IOCP, neben den bestehenden Einstellungen EPOLLThreads, IOCPThreads und WorkOpThreads. Sie sind standardmäßig deaktiviert, sodass sich für bestehende Server nichts ändert, solange Sie sie nicht aktivieren.
Laden Sie die Testversion herunter und lesen Sie die vollständige IOCP- und EPOLL-Referenz auf der Produktseite von sgcWebSockets.
Fragen oder Feedback? Kontaktieren Sie uns, Sie erhalten eine Antwort von den Leuten, die den Code geschrieben haben.
