De IOCP- (Windows) en EPOLL- (Linux) server-engines in sgcWebSockets verwerken duizenden verbindingen met een kleine pool threads in plaats van één thread per verbinding, en dat is precies wat ze de juiste keuze maakt voor servers onder zware gelijktijdige belasting. Tot nu toe hadden ze echter geen manier om te merken dat een peer stil wordt zonder afscheid te nemen. Twee nieuwe opties, TCPKeepAlive en KeepAliveTimeout, dichten dat gat.
Een stille peer levert nooit een event op
IOCP en EPOLL zijn event-driven: de engine slaapt totdat het besturingssysteem meldt dat een socket data heeft, gesloten is of een fout heeft. Dat werkt prima, totdat een peer verdwijnt zonder een schone FIN of RST te versturen, bijvoorbeeld een client die crasht, een NAT of firewall die een inactieve mapping laat vervallen, of een route die stilletjes verandert. Er komt nooit een event voor die socket binnen, dus de verbinding blijft op de server voor onbepaalde tijd op ESTABLISHED staan.
De klassieke thread-per-verbinding IOHandler heeft dit probleem niet, omdat elke verbinding blokkeert op een read met een timeout, waardoor een stille verbinding wordt opgemerkt en vrijgegeven zodra die read verloopt. IOCP en EPOLL hadden geen vergelijkbaar mechanisme, en dat is precies wat deze twee nieuwe opties toevoegen.
TCPKeepAlive: laat het besturingssysteem meekijken
Schakel TCPKeepAlive in en het besturingssysteem zelf begint een verbinding te controleren zodra deze Time seconden inactief is geweest, en herhaalt dit elke Interval seconden totdat de peer antwoordt of de verbinding wordt verbroken. De optie staat standaard uit; de onderstaande waarden komen overeen met de standaardwaarden wanneer ze is ingeschakeld.
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
Op een Windows-server bevinden dezelfde drie eigenschappen zich onder IOHandlerOptions.IOCP.TCPKeepAlive.
KeepAliveTimeout: een idle-timeout op applicatieniveau
KeepAliveTimeout kiest een andere, meer directe aanpak: het sluit elke verbinding die langer inactief is gebleven dan het opgegeven aantal seconden, ongeacht wat de keepalive-probes van het besturingssysteem besluiten. Dit komt het dichtst in de buurt van hoe de thread-per-verbinding IOHandler al een stille verbinding vrijgeeft, staat standaard uit (een waarde van 0), en alleen echt inactieve verbindingen worden erdoor beïnvloed; een request die wordt gelezen of een response die wordt geschreven, wordt er nooit door onderbroken.
Server.IOHandlerOptions.EPOLL.KeepAliveTimeout := 120; // seconds
// Windows
Server.IOHandlerOptions.IOCP.KeepAliveTimeout := 120;
Stel de waarde ruim boven je traagst verwachte request of response in, bijvoorbeeld 120 seconden voor een typische HTTP- of WebSocket-server, zodat werkelijk dode verbindingen snel worden opgeruimd zonder ooit een verbinding te raken die gewoon traag is.
Een derde manier om een verbroken verbinding te detecteren
sgcWebSockets bood al twee manieren om te merken dat een peer weg is: CleanDisconnect inschakelen op TsgcWebSocketClient, zodat een goed geïmplementeerde client de server laat weten dat hij vertrekt, of een server-side heartbeat draaien die elke client op een interval pingt. Beide zijn afhankelijk van medewerking, van de client in het eerste geval, van je eigen ping/pong-rondgang in het tweede. TCPKeepAlive en KeepAliveTimeout zijn de eerste optie die niets van dat alles nodig heeft: de server detecteert een dode verbinding volledig op eigen kracht.
Beschikbaarheid
Beide opties zijn nu beschikbaar in sgcWebSockets voor Delphi en C++ Builder 7 tot en met 13, onder IOHandlerOptions.EPOLL en IOHandlerOptions.IOCP, naast de bestaande instellingen EPOLLThreads, IOCPThreads en WorkOpThreads. Ze staan standaard uit, dus er verandert niets voor bestaande servers tenzij je ze inschakelt.
Download de proefversie en lees de volledige IOCP- en EPOLL-referentie op de sgcWebSockets-productpagina.
Vragen of feedback? Neem contact op, je krijgt een antwoord van de mensen die de code hebben geschreven.
