Les moteurs de serveur IOCP (Windows) et EPOLL (Linux) de sgcWebSockets gèrent des milliers de connexions avec un petit pool de threads au lieu d'un thread par connexion, ce qui en fait le bon choix pour les serveurs soumis à une forte charge concurrente. Jusqu'à présent, cependant, ils n'avaient aucun moyen de détecter un pair qui se tait sans dire au revoir. Deux nouvelles options, TCPKeepAlive et KeepAliveTimeout, comblent cette lacune.
Un pair silencieux ne produit jamais d'événement
IOCP et EPOLL fonctionnent par événements : le moteur reste en veille jusqu'à ce que le système d'exploitation lui indique qu'un socket a des données, s'est fermé ou a rencontré une erreur. Cela fonctionne bien, jusqu'à ce qu'un pair disparaisse sans envoyer de FIN ou de RST propre, par exemple un client qui plante, un NAT ou un pare-feu qui abandonne un mappage inactif, ou une route qui change silencieusement. Aucun événement n'arrive jamais pour ce socket, de sorte que la connexion reste ESTABLISHED sur le serveur indéfiniment.
Le IOHandler classique à un thread par connexion n'a pas ce problème, car chaque connexion se bloque sur une lecture avec un délai d'expiration, de sorte qu'une connexion silencieuse est détectée et libérée la prochaine fois que cette lecture expire. IOCP et EPOLL n'avaient aucun mécanisme équivalent, ce qui est exactement ce qu'ajoutent ces deux nouvelles options.
TCPKeepAlive : laisser le système d'exploitation surveiller
Activez TCPKeepAlive et le système d'exploitation lui-même commence à sonder une connexion dès qu'elle est restée inactive pendant Time secondes, en répétant l'opération toutes les Interval secondes jusqu'à ce que le pair réponde ou que la connexion soit abandonnée. Cette option est désactivée par défaut ; les valeurs ci-dessous correspondent aux valeurs par défaut une fois activée.
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
Sur un serveur Windows, les trois mêmes propriétés se trouvent sous IOHandlerOptions.IOCP.TCPKeepAlive.
KeepAliveTimeout : un délai d'inactivité au niveau applicatif
KeepAliveTimeout adopte une approche différente, plus directe : elle ferme toute connexion restée inactive plus longtemps que le nombre de secondes indiqué, indépendamment de ce que décident les sondes keepalive du système d'exploitation. C'est ce qui se rapproche le plus de la façon dont le IOHandler à un thread par connexion libère déjà une connexion silencieuse, elle est désactivée par défaut (une valeur de 0), et seules les connexions réellement inactives sont concernées, une requête en cours de lecture ou une réponse en cours d'écriture n'est jamais interrompue par cette option.
Server.IOHandlerOptions.EPOLL.KeepAliveTimeout := 120; // seconds
// Windows
Server.IOHandlerOptions.IOCP.KeepAliveTimeout := 120;
Réglez-la confortablement au-dessus de votre requête ou réponse la plus lente attendue, par exemple 120 secondes pour un serveur HTTP ou WebSocket typique, afin que les connexions réellement mortes soient récupérées rapidement sans jamais toucher à une connexion simplement lente.
Une troisième façon de détecter une déconnexion
sgcWebSockets proposait déjà deux moyens de détecter la disparition d'un pair : activer CleanDisconnect sur TsgcWebSocketClient, afin qu'un client bien élevé prévienne le serveur avant de partir, ou exécuter un heartbeat côté serveur qui envoie un ping à chaque client à intervalle régulier. Les deux dépendent d'une coopération, celle du client dans le premier cas, celle de votre propre aller-retour ping/pong dans le second. TCPKeepAlive et KeepAliveTimeout sont la première option qui n'a besoin de rien de tout cela : le serveur détecte une connexion morte entièrement par lui-même.
Disponibilité
Les deux options sont désormais disponibles dans sgcWebSockets pour Delphi et C++ Builder 7 à 13, sous IOHandlerOptions.EPOLL et IOHandlerOptions.IOCP, aux côtés des paramètres existants EPOLLThreads, IOCPThreads et WorkOpThreads. Elles sont désactivées par défaut, de sorte que rien ne change pour les serveurs existants tant que vous ne les activez pas.
Téléchargez la version d'essai et consultez la référence complète IOCP et EPOLL sur la page produit sgcWebSockets.
Des questions ou des retours ? Contactez-nous, vous recevrez une réponse des personnes qui ont écrit le code.
