sgcWebSockets 2026.5 est une version costaude. Trois nouveaux composants d'infrastructure transforment le serveur WebSocket / HTTP en une passerelle API de qualité production : un limiteur de débit complet, un disjoncteur côté client, et un gestionnaire de clés API avec prise en charge complète du cycle de vie. Côté protocole, il y a un nouveau client Forex.com bâti sur une implémentation générique Lightstreamer TLCP 2.5, le serveur MCP gagne un flux OAuth 2.1 intégré qui lui permet de se connecter directement aux clients MCP basés sur navigateur tels que claude.ai, et les moteurs d'E/S IOCP (Windows) et EPOLL (Linux) bénéficient de six gains de performance mesurables. Il y a aussi une primitive post-quantique précoce : sgcKEM_CreateMLKEM768Keys pour la génération de paires de clés ML-KEM-768.
Cet article passe en revue les points forts avec des extraits Delphi prêts à coller pour les nouveaux composants.
TsgcWSRateLimiter — limitation de débit API prête à l'emploi
Déposez un TsgcWSRateLimiter à côté de votre serveur et vous obtenez une limitation de débit par seau à jetons, fenêtre glissante ou fenêtre fixe par IP, par clé API, par utilisateur ou par motif de point de terminaison, plus des quotas quotidiens/mensuels et une protection contre les rafales. Le composant est thread-safe et persiste son état sur le disque (donc un redémarrage du serveur n'accorde pas à chaque client une nouvelle allocation).
uses
sgcWebSocket_Server_RateLimiter;
var
oRL: TsgcWSRateLimiter;
oResult: TsgcRateLimitResult;
begin
oRL := TsgcWSRateLimiter.Create(nil);
try
oRL.TokenBucket.Enabled := True;
oRL.TokenBucket.Capacity := 100; // burst size
oRL.TokenBucket.RefillRate := 10; // tokens / interval
oRL.TokenBucket.RefillIntervalMs := 1000;
oRL.PerIP.Enabled := True;
oRL.PerIP.MaxRequests := 60;
oRL.PerIP.WindowSec := 60;
// Consume one token for the current request
oResult := oRL.Consume('ip:' + vClientIP);
if not oResult.Allowed then
RespondHTTP(429, 'Retry-After: ' + IntToStr(oResult.RetryAfterSec));
finally
oRL.Free;
end;
end;
Le résolveur de règles parcourt PerEndpoint (correspondance par caractères génériques), puis PerAPIKey, PerUser, et enfin PerIP. Les événements OnThrottled, OnQuotaExceeded et OnStateChange vous permettent de journaliser ou de remplacer chaque décision.
Démo : Demos\04.WebSocket_Other_Samples\14.RateLimiter — exécute un client générateur de flood contre un serveur qui publie des statistiques en direct et les raisons de rejet.
TsgcWSCircuitBreaker — isolation des pannes côté client
Lorsqu'une API en amont (api.openai.com, une passerelle de paiement, un microservice interne) commence à échouer ou à ralentir, rester suspendu sur des dépassements de délai TCP vous coûte des connexions, des threads et de l'argent. TsgcWSCircuitBreaker implémente le motif classique à trois états (fermé / ouvert / semi-ouvert) au-dessus de toute sous-classe TsgcHTTPAPI_client, avec une fenêtre temporelle glissante, la détection d'appels lents, des réponses de repli optionnelles et des remplacements par point de terminaison.
uses
sgcWebSocket_CircuitBreaker;
var
oCB: TsgcWSCircuitBreaker;
begin
oCB := TsgcWSCircuitBreaker.Create(nil);
try
oCB.Thresholds.FailureCount := 5;
oCB.Thresholds.FailureRatePercent := 50;
oCB.Thresholds.SlowCallDurationMs := 2000;
oCB.Thresholds.SlowCallRatePercent := 80;
oCB.TimeWindow.RollingWindowSec := 60;
oCB.Recovery.CooldownSec := 30;
oCB.Recovery.HalfOpenTrialCalls := 3;
oCB.Fallback.Enabled := True;
oCB.Fallback.UseLastSuccess := True;
if oCB.IsCallAllowed('openai') then
try
vResponse := oOpenAI.ChatCompletion(...);
oCB.RecordSuccess('openai');
except
on E: Exception do
begin
oCB.RecordFailure('openai', E.ClassName);
raise;
end;
end
else
vResponse := 'service temporarily unavailable';
finally
oCB.Free;
end;
end;
Sur Delphi 2009+, un wrapper en une seule ligne est également disponible : oCB.Execute('openai', procedure begin oOpenAI.ChatCompletion(...) end); — l'enregistrement du succès / de l'échec se produit automatiquement.
Démo : Demos\04.WebSocket_Other_Samples\15.CircuitBreaker.
TsgcWSAPIKeyManager — cycle de vie des clés dans un seul composant
La plupart des serveurs « API WebSocket » ont besoin de clés API : émettre, valider, révoquer, faire tourner. TsgcWSAPIKeyManager enveloppe le cycle de vie complet avec une autorisation basée sur les portées, un hachage au repos optionnel, l'expiration, un journal d'audit, et une période de grâce intégrée pour la rotation afin que les anciennes clés continuent à fonctionner pendant une fenêtre configurable après la rotation.
uses
sgcWebSocket_Server_APIKeyManager;
var
oKM: TsgcWSAPIKeyManager;
vKey, vNewKey: string;
begin
oKM := TsgcWSAPIKeyManager.Create(nil);
try
oKM.Generation.Length := 40;
oKM.Generation.Prefix := 'sgc_';
oKM.Hashing.Enabled := True; // store SHA-256 hash, not the plaintext
oKM.Rotation.GracePeriodSec := 86400; // old key valid for 24h after rotation
oKM.Expiration.DefaultTTLSec := 30 * 86400;
// Issue a key for tenant "acme" with read+write scopes, expiring in 7 days
vKey := oKM.IssueKey('acme', ['read', 'write'], 7 * 86400);
// Validate the key on each request, optionally requiring a scope
if not oKM.ValidateKey(vKey, 'read', vClientIP) then
RespondHTTP(401, 'invalid api key');
// Rotate a key (returns the new plaintext; old key remains valid for GracePeriodSec)
oKM.RotateKey(vKey, vNewKey);
finally
oKM.Free;
end;
end;
Le composant peut lire la clé directement depuis les en-têtes HTTP entrants ou la chaîne de requête avec IsRequestAuthorized, vous n'avez donc pas à câbler l'extraction vous-même.
Démo : Demos\04.WebSocket_Other_Samples\16.APIKeyManager.
Client Forex.com + Lightstreamer générique
Le nouveau client TsgcWSAPI_Forex offre un accès REST + streaming unifié à Forex.com (connexion, ping, surveillance du marché, positions, ordres, historique des transactions, transaction simulée). Il est bâti sur un tout nouveau composant TsgcWSPClient_Lightstreamer, un client générique Lightstreamer TLCP 2.5 qui implémente create_session, bind_session, control (subscribe / unsubscribe) et la relance automatique LOOP + la rediffusion d'abonnement après reconnexion. Le client Lightstreamer est réutilisable indépendamment, donc la même base de code fonctionne avec IG Markets et tout autre flux propulsé par Lightstreamer.
uses sgcHTTP_API_Forex;
var oFX: TsgcWSAPI_Forex;
begin
oFX := TsgcWSAPI_Forex.Create(nil);
oFX.UserName := 'demo-user';
oFX.Password := 'secret';
oFX.AppKey := 'your-app-key';
oFX.Login;
oFX.SubscribePrices(['EUR/USD', 'GBP/USD', 'XAU/USD']);
oFX.OnPriceUpdate := procedure(const aSymbol: string; aBid, aAsk: Double)
begin
ShowMessage(Format('%s %.5f / %.5f', [aSymbol, aBid, aAsk]));
end;
end;
Une démo GUI complète se trouve dans Demos\05.Crypto\22.Forex — connexion, ping de connectivité, surveillance du marché en direct, positions, ordres actifs, historique des transactions, historique des stop / limit et transaction simulée, avec les identifiants persistés dans sgcForexDemo.ini.
Serveur MCP — OAuth 2.1 pour les clients MCP basés sur navigateur
Le serveur MCP peut désormais communiquer directement avec les connecteurs MCP basés sur navigateur (tels que claude.ai) sans serveur d'autorisation externe. Il publie automatiquement les quatre points de terminaison de découverte / enregistrement OAuth requis par la spécification du connecteur navigateur MCP, exécute un flux d'autorisation PKCE-S256 avec un écran de consentement HTML, et émet des jetons de rafraîchissement :
GET /.well-known/oauth-authorization-server— métadonnées RFC 8414.GET /.well-known/oauth-protected-resource— métadonnées de ressource protégée RFC 9728.POST /oauth/register— enregistrement client dynamique RFC 7591.GET /oauth/authorize— formulaire de consentement HTML.POST /oauth/token— PKCE S256 + jetons de rafraîchissement.
CORS est géré en ligne : le préflight OPTIONS renvoie 204 avec les en-têtes Access-Control-* complets avant l'authentification, chaque réponse porte un Access-Control-Allow-Origin reflétant l'origine de la requête et un en-tête HSTS Strict-Transport-Security: max-age=31536000.
IOCP et EPOLL : six gains de réglage
Les moteurs d'E/S Windows IOCP et Linux EPOLL ont bénéficié d'une série ciblée de travaux de performance et de réglage.
IOCP (Windows)
ThreadAffinity(par défautFalse) surTsgcIndy_IO_Engine— épingle les threads du moteur en round-robin sur les cœurs logiques viaSetThreadAffinityMask. Réduit le trafic de cache inter-cœurs sur les systèmes à grand nombre de cœurs.Metrics— un nouvel enregistrementTsgcIndy_IO_EngineMetrics(AcceptsPosted,AcceptsCompleted,ReadsPosted,ReadsCompleted,ActiveConnections,BytesRead,BytesWritten) mis à jour sous une section critique. Plus besoin de deviner.SendBufferSize,ReceiveBufferSize,TCPNoDelaysurTsgcIndy_IOHandler_IO_IOCP— appliqués dansAfterAcceptviasetsockopt, de sorte que le réglage par connexion ne nécessite plus de gestionnaireOnConnectpersonnalisé.TsgcPerIoDataPoolcapacité augmentée de 256 à 2048, évitant le repli sur le tasGetMem/FreeMemsous forte concurrence de connexions. +15–18 % de débit WebSocket sur les benchmarks en boucle locale.
oServer.Bindings.Add.Port := 443;
oServer.IOHandler := TsgcIndy_IOHandler_IO_IOCP.Create(oServer);
with TsgcIndy_IOHandler_IO_IOCP(oServer.IOHandler) do
begin
SendBufferSize := 256 * 1024;
ReceiveBufferSize := 256 * 1024;
TCPNoDelay := True;
Engine.ThreadAffinity := True;
end;
EPOLL (Linux)
AcceptBatchSize,WaitTimeoutMS,HandshakeTimeoutMS— règlent la boucle d'acceptation et la protection slow-loris.- Backpressure d'écriture pilotée par EPOLLOUT — lorsque
send()renvoieEAGAINsur une écriture partielle, les octets restants sont capturés dans un tampon en attente par connexion et le socket est ré-armé avecEPOLLIN|EPOLLOUT. Le réacteur vide la queue lors du prochain événementEPOLLOUTau lieu de laisser tomber les octets ou de bloquer le worker.
Partagé
Le pool de workers IOCP / EPOLL exécutait sleep(1) à chaque itération y compris juste après le traitement d'une tâche — plafonnant effectivement chaque worker à environ 1 000 ops/s même lorsque la file d'attente était pleine. Le sleep est maintenant ignoré tant qu'il y a du travail en attente, supprimant le plafond.
HTTP.sys : mode haute performance opt-in
Le serveur HTTP.sys gagne une propriété FineTune avec un sélecteur OperatingMode. La valeur par défaut ompClassic préserve le comportement existant. Le nouveau mode ompHighPerf implémente le motif MSDN N-workers × M-réceptions-async-pré-postées — l'architecture recommandée pour les déploiements HTTP.sys à haut débit — derrière une seule propriété :
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.HTTP2Options.SecureOptions.HTTPAPI := True; // use HTTP.sys
oServer.FineTune.OperatingMode := ompHighPerf;
oServer.FineTune.WorkerCount := 8;
oServer.FineTune.PrePostedReceivesPerWorker := 16;
oServer.Active := True;
THttpServerRequest et THttpServerResponse ont également été étendus avec des champs supplémentaires couvrant des détails auparavant disponibles uniquement par analyse manuelle.
Primitive post-quantique : ML-KEM-768
Un petit ajout mais tourné vers l'avenir : sgcKEM_CreateMLKEM768Keys génère une paire de clés ML-KEM-768 (FIPS 203 / Kyber-768) à la fois sous forme PEM et octets bruts. ML-KEM est le KEM post-quantique normalisé par le NIST et figurant sur la feuille de route de l'IETF pour TLS 1.3 hybride (X25519MLKEM768). Cela débloque l'expérimentation avec des handshakes prêts pour le PQ avant la prochaine ligne de base OpenSSL 3.5 / 3.6.
uses sgcKEM;
var vPubPEM, vPrivPEM: string; vPubRaw, vPrivRaw: TBytes;
begin
sgcKEM_CreateMLKEM768Keys(vPubPEM, vPrivPEM, vPubRaw, vPrivRaw);
TFile.WriteAllText('mlkem768_pub.pem', vPubPEM);
TFile.WriteAllText('mlkem768_priv.pem', vPrivPEM);
end;
Corrections de fiabilité et de conformité
Le lot de corrections de bogues clôt une longue liste de problèmes MCP, HTTP.sys, IOCP et HTTP/2. Points forts :
- Serveur MCP — les identifiants manquants ou invalides renvoient maintenant
401 Unauthorizedavec un en-têteWWW-Authenticate: Bearerpointant vers les métadonnées de ressource protégée, au lieu de500 Internal Server Error. Requis pour la découverte OAuth par les clients MCP basés sur navigateur. - Serveur MCP — les requêtes
OPTIONSn'atteignent plus l'analyseur JSON-RPC (qui renvoyait auparavant500 "Invalid jsonrpc Value"). Le préflight CORS est maintenant géré avant l'authentification et avant l'analyseur de corps MCP. - Serveur MCP — les descriptions d'outils, les messages d'invite et le contenu des ressources contenant des caractères non-ASCII ne rompent plus la connexion (le corps JSON correspond maintenant au
charset=utf-8déclaré). - Serveur MCP — les champs
named'tool/prompt/resource/root/template/ completion-ref et completion-argument contenant des caractères non-ASCII sont maintenant correctement émis et lus en tant qu'échappements JSON\uXXXXplutôt que points de code UTF-16 bruts. - Corps de requête API HTTP —
TsgcWSComponent_Server.DoHTTPRequestAPIappelaitReadStringFromStreamsans spécifier d'encodage, défaillant à ASCII et substituant chaque octet non-ASCII par?avant que les gestionnaires d'événements ne le voient. Corrigé. - Serveur HTTP.sys — fuite de contexte sur
ERROR_MORE_DATAdansTsgcHTTPServerAPI.DoExecute. La boucle d'acceptation augmente maintenant le tampon et réessaieHttpReceiveHttpRequestsur le même identifiant de requête, et libère les contextes orphelins sur tous les chemins d'erreur. - Serveur HTTP.sys —
TsgcWSConnectionServer_HTTPAPI.DoSendHTTP_Responsene définit plusHTTP_SEND_RESPONSE_FLAG_MORE_DATAsur la réponse finale. - IOCP IOHandler —
TsgcIndy_IO_Engine_IOCP_Base.DoStopThreadsappelaitWaitForMultipleObjectssur un tableau d'identifiants de threadDWORD(FThreadsId) au lieu de HANDLEs de thread. Corrigé. - IOCP IOHandler — les opérations d'E/S en attente sur les sockets sont maintenant annulées à l'arrêt et à la fermeture par socket.
- IOCP IOHandler — la sonde fragile
Overlapped.Internal = STATUS_PENDINGdansDoFreePerIoDataest remplacée par un drapeau expliciteCompleted: BooleansurTsgcPerIoData. - HTTP/2 WebBrokerBridge — Opération de pointeur invalide sur
sgcFree(oResponse)dansTsgcWSHTTPServer.OnHTTP2RequestEventlorsque DataSnap REST gérait une trame HTTP/2HEADERS-only.
Mise à niveau
2026.5 est une mise à niveau prête à l'emploi pour les projets 2026.4 existants. Aucune modification d'interface n'a été apportée aux composants existants ; les nouveaux composants de limiteur de débit / disjoncteur / clé API sont additifs et opt-in. Le mode haute performance HTTP.sys est verrouillé derrière FineTune.OperatingMode := ompHighPerf — le code existant reste sur le chemin classique.
Les clients avec un abonnement actif peuvent télécharger la nouvelle version depuis l'espace client. Les utilisateurs d'essai peuvent récupérer le programme d'installation mis à jour sur esegece.com/products/sgcwebsockets/sgcwebsockets-download.
Des questions, retours ou aide à la migration ? Contactez-nous — vous obtiendrez une réponse des personnes qui ont écrit le code.
