sgcWebSockets 2026.5 to wydanie z konkretną zawartością. Trzy nowe komponenty infrastrukturalne zmieniają serwer WebSocket / HTTP w bramę API klasy produkcyjnej: w pełni funkcjonalny ogranicznik szybkości (rate limiter), wyłącznik bezpiecznikowy (circuit breaker) po stronie klienta oraz menedżer kluczy API z pełnym wsparciem cyklu życia. Po stronie protokołów pojawia się nowy klient Forex.com zbudowany na ogólnej implementacji Lightstreamer TLCP 2.5, serwer MCP zyskuje wbudowany przepływ OAuth 2.1, dzięki czemu może łączyć się bezpośrednio z przeglądarkowymi klientami MCP, takimi jak claude.ai, a silniki I/O IOCP (Windows) i EPOLL (Linux) otrzymują sześć mierzalnych zysków wydajności. Jest też wczesny element postkwantowy: sgcKEM_CreateMLKEM768Keys do generowania par kluczy ML-KEM-768.
Ten wpis przeprowadza przez najważniejsze nowości wraz z gotowymi do wklejenia fragmentami kodu Delphi dla nowych komponentów.
TsgcWSRateLimiter — gotowe ograniczanie szybkości API
Umieść TsgcWSRateLimiter obok swojego serwera, a uzyskasz ograniczanie szybkości typu token-bucket, sliding-window lub fixed-window per IP, per klucz API, per użytkownik lub per wzorzec punktu końcowego, a także kwoty dzienne/miesięczne i ochronę przed nagłymi skokami ruchu. Komponent jest bezpieczny wątkowo i utrwala stan na dysku (więc restart serwera nie daje każdemu klientowi świeżej puli).
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;
Mechanizm rozstrzygania reguł sprawdza PerEndpoint (dopasowanie z symbolami wieloznacznymi), następnie PerAPIKey, PerUser, a na końcu PerIP. Zdarzenia OnThrottled, OnQuotaExceeded i OnStateChange pozwalają zarejestrować lub nadpisać każdą decyzję.
Demo: Demos\04.WebSocket_Other_Samples\14.RateLimiter — uruchamia klienta generującego zalew żądań przeciwko serwerowi, który publikuje statystyki na żywo i przyczyny odrzucenia.
TsgcWSCircuitBreaker — izolacja awarii po stronie klienta
Gdy zewnętrzne API (api.openai.com, bramka płatności, wewnętrzny mikroserwis) zaczyna zawodzić lub spowalniać, zawieszanie się na timeoutach TCP kosztuje połączenia, wątki i pieniądze. TsgcWSCircuitBreaker implementuje klasyczny wzorzec trzech stanów (zamknięty / otwarty / półotwarty) na bazie dowolnej podklasy TsgcHTTPAPI_client, z toczącym się oknem czasowym, wykrywaniem powolnych wywołań, opcjonalnymi odpowiedziami zastępczymi oraz nadpisaniami per punkt końcowy.
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;
W Delphi 2009+ dostępna jest również wersja jednowierszowa: oCB.Execute('openai', procedure begin oOpenAI.ChatCompletion(...) end); — rejestracja powodzeń / niepowodzeń odbywa się automatycznie.
Demo: Demos\04.WebSocket_Other_Samples\15.CircuitBreaker.
TsgcWSAPIKeyManager — cykl życia kluczy w jednym komponencie
Większość serwerów "WebSocket API" potrzebuje kluczy API: wystawianie, walidacja, unieważnianie, rotacja. TsgcWSAPIKeyManager obejmuje pełny cykl życia z autoryzacją opartą na zakresach, opcjonalnym haszowaniem w spoczynku, wygaśnięciem, dziennikiem audytu i wbudowanym okresem karencji po rotacji, dzięki czemu stare klucze działają jeszcze przez konfigurowalne okno po rotacji.
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;
Komponent może odczytać klucz bezpośrednio z przychodzących nagłówków HTTP lub z query stringa za pomocą IsRequestAuthorized, więc nie trzeba samodzielnie programować jego ekstrakcji.
Demo: Demos\04.WebSocket_Other_Samples\16.APIKeyManager.
Klient Forex.com + ogólny Lightstreamer
Nowy klient TsgcWSAPI_Forex oferuje ujednolicony dostęp REST + streaming do Forex.com (logowanie, ping, market watch, pozycje, zlecenia, historia transakcji, symulacja transakcji). Jest zbudowany na zupełnie nowym komponencie TsgcWSPClient_Lightstreamer, ogólnym kliencie Lightstreamer TLCP 2.5, który implementuje create_session, bind_session, control (subskrybuj / odsubskrybuj) oraz auto-rebind pętli LOOP i odtwarzanie subskrypcji po ponownym połączeniu. Klient Lightstreamer jest wielokrotnego użytku samodzielnie, więc ta sama baza kodu działa z IG Markets i każdym innym strumieniem opartym na 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;
Pełne demo z GUI znajduje się w Demos\05.Crypto\22.Forex — logowanie, ping łączności, market watch na żywo, pozycje, aktywne zlecenia, historia transakcji, historia stop / limit oraz symulacja transakcji, z poświadczeniami utrwalanymi w sgcForexDemo.ini.
Serwer MCP — OAuth 2.1 dla przeglądarkowych klientów MCP
Serwer MCP może teraz rozmawiać bezpośrednio z przeglądarkowymi konektorami MCP (takimi jak claude.ai) bez zewnętrznego serwera autoryzacji. Automatycznie publikuje cztery punkty końcowe odkrywania / rejestracji OAuth wymagane przez specyfikację konektorów przeglądarkowych MCP, uruchamia przepływ autoryzacji PKCE-S256 z ekranem zgody HTML i wystawia tokeny odświeżania:
GET /.well-known/oauth-authorization-server— metadane RFC 8414.GET /.well-known/oauth-protected-resource— metadane chronionego zasobu RFC 9728.POST /oauth/register— dynamiczna rejestracja klienta RFC 7591.GET /oauth/authorize— formularz zgody HTML.POST /oauth/token— PKCE S256 + tokeny odświeżania.
CORS jest obsługiwany w trakcie: preflight OPTIONS zwraca 204 z pełnymi nagłówkami Access-Control-* przed uwierzytelnieniem, każda odpowiedź zawiera odzwierciedlenie Access-Control-Allow-Origin pochodzenia żądania oraz nagłówek HSTS Strict-Transport-Security: max-age=31536000.
IOCP i EPOLL: sześć zysków z dostrojenia
Silniki I/O Windows IOCP i Linux EPOLL otrzymały skoncentrowaną rundę prac nad wydajnością i możliwością strojenia.
IOCP (Windows)
ThreadAffinity(domyślnieFalse) wTsgcIndy_IO_Engine— przypina wątki silnika cyklicznie do logicznych rdzeni poprzezSetThreadAffinityMask. Zmniejsza ruch międzyrdzeniowy w cache na systemach z dużą liczbą rdzeni.Metrics— nowy rekordTsgcIndy_IO_EngineMetrics(AcceptsPosted,AcceptsCompleted,ReadsPosted,ReadsCompleted,ActiveConnections,BytesRead,BytesWritten) aktualizowany pod sekcją krytyczną. Koniec ze zgadywaniem.SendBufferSize,ReceiveBufferSize,TCPNoDelaywTsgcIndy_IOHandler_IO_IOCP— stosowane wAfterAcceptprzezsetsockopt, więc dostrajanie per połączenie nie wymaga już własnej procedury obsługiOnConnect.- Pojemność
TsgcPerIoDataPoolzwiększona z 256 do 2048, co pozwala uniknąć zapasowego mechanizmu stertyGetMem/FreeMemprzy dużej równoczesności połączeń. +15–18% przepustowości WebSocket w testach pętli zwrotnej.
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— dostrajają pętlę accept i strażnika slow-loris.- Wstecz-ciśnienie zapisu sterowane EPOLLOUT — gdy
send()zwracaEAGAINprzy zapisie częściowym, pozostałe bajty są przechwytywane w buforze oczekującym per połączenie, a gniazdo jest ponownie uzbrajane zEPOLLIN|EPOLLOUT. Reaktor opróżnia ogon przy następnym zdarzeniuEPOLLOUTzamiast porzucać bajty lub blokować wątek roboczy.
Wspólne
Pula wątków roboczych IOCP / EPOLL wykonywała sleep(1) przy każdej iteracji łącznie z momentem zaraz po przetworzeniu zadania — co efektywnie ograniczało każdego workera do ~1000 operacji/s, nawet gdy kolejka była pełna. Uśpienie jest teraz pomijane, gdy są zadania oczekujące, co usuwa to ograniczenie.
HTTP.sys: opcjonalny tryb wysokiej wydajności
Serwer HTTP.sys zyskuje właściwość FineTune z selektorem OperatingMode. Domyślny ompClassic zachowuje istniejące zachowanie. Nowy tryb ompHighPerf implementuje wzorzec MSDN N-workerów × M-wstępnie-wystawionych-odbiorów-async — rekomendowaną architekturę dla wysokoprzepustowych wdrożeń HTTP.sys — za pojedynczą właściwością:
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 i THttpServerResponse zostały także rozszerzone o dodatkowe pola obejmujące szczegóły wcześniej dostępne tylko przez ręczne parsowanie.
Element postkwantowy: ML-KEM-768
Niewielki, ale przyszłościowy dodatek: sgcKEM_CreateMLKEM768Keys generuje parę kluczy ML-KEM-768 (FIPS 203 / Kyber-768) zarówno w postaci PEM, jak i surowych bajtów. ML-KEM to postkwantowy KEM ustandaryzowany przez NIST i znajdujący się na mapie drogowej IETF dla hybrydowego TLS 1.3 (X25519MLKEM768). Odblokowuje to eksperymentowanie z handshake'ami gotowymi na PQ jeszcze przed nadchodzącą bazą 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;
Poprawki niezawodności i zgodności
Pakiet poprawek zamyka długą listę problemów MCP, HTTP.sys, IOCP i HTTP/2. Najważniejsze:
- Serwer MCP — brakujące lub nieprawidłowe poświadczenia zwracają teraz
401 Unauthorizedz nagłówkiemWWW-Authenticate: Bearerwskazującym na metadane chronionego zasobu, zamiast500 Internal Server Error. Wymagane przy odkrywaniu OAuth przez przeglądarkowych klientów MCP. - Serwer MCP — żądania
OPTIONSnie trafiają już do parsera JSON-RPC (wcześniej zwracały500 "Invalid jsonrpc Value"). Preflight CORS jest teraz obsługiwany przed uwierzytelnieniem i przed parserem treści MCP. - Serwer MCP — opisy narzędzi, treści promptów i zawartości zasobów zawierające znaki spoza ASCII nie zrywają już połączenia (treść JSON odpowiada teraz zadeklarowanemu
charset=utf-8). - Serwer MCP — pola
namewtool/prompt/resource/root/template/ completion-ref i completion-argument zawierające znaki spoza ASCII są teraz poprawnie emitowane i odczytywane jako escape JSON\uXXXX, a nie surowe punkty kodowe UTF-16. - Treść żądania HTTP API —
TsgcWSComponent_Server.DoHTTPRequestAPIwywoływałReadStringFromStreambez podawania kodowania, domyślnie używając ASCII i zastępując każdy bajt spoza ASCII znakiem?, zanim procedury obsługi zdarzeń go zobaczyły. Naprawione. - Serwer HTTP.sys — wyciek kontekstu przy
ERROR_MORE_DATAwTsgcHTTPServerAPI.DoExecute. Pętla accept rozszerza teraz bufor i ponawiaHttpReceiveHttpRequestna tym samym identyfikatorze żądania, a osierocone konteksty są zwalniane na wszystkich ścieżkach błędu. - Serwer HTTP.sys —
TsgcWSConnectionServer_HTTPAPI.DoSendHTTP_Responsenie ustawia jużHTTP_SEND_RESPONSE_FLAG_MORE_DATAw ostatecznej odpowiedzi. - IOCP IOHandler —
TsgcIndy_IO_Engine_IOCP_Base.DoStopThreadswywoływałWaitForMultipleObjectsna tablicy identyfikatorów wątkówDWORD(FThreadsId) zamiast na uchwytach wątków. Naprawione. - IOCP IOHandler — oczekujące operacje I/O na gniazdach są teraz anulowane przy zamknięciu oraz przy zamknięciu per gniazdo.
- IOCP IOHandler — kruchy test
Overlapped.Internal = STATUS_PENDINGwDoFreePerIoDatazostał zastąpiony jawną flagąCompleted: BooleanwTsgcPerIoData. - HTTP/2 WebBrokerBridge — Invalid pointer operation w
sgcFree(oResponse)wTsgcWSHTTPServer.OnHTTP2RequestEvent, gdy DataSnap REST obsługiwał ramkę HTTP/2 zawierającą tylkoHEADERS.
Aktualizacja
2026.5 to aktualizacja typu drop-in dla istniejących projektów 2026.4. W istniejących komponentach nie wprowadzono zmian interfejsu; nowe komponenty rate-limit / circuit-breaker / API-key są addytywne i opcjonalne. Tryb wysokiej wydajności HTTP.sys jest dostępny po ustawieniu FineTune.OperatingMode := ompHighPerf — istniejący kod pozostaje na klasycznej ścieżce.
Klienci z aktywną subskrypcją mogą pobrać nową kompilację z obszaru klienta. Użytkownicy wersji testowej mogą pobrać zaktualizowany instalator pod adresem esegece.com/products/sgcwebsockets/sgcwebsockets-download.
Pytania, opinie lub pomoc przy migracji? Skontaktuj się z nami — otrzymasz odpowiedź od ludzi, którzy napisali ten kod.
