sgcWebSockets 2026.7 to wydanie o pracy na produkcji. Możesz teraz rozłożyć aplikację WebSocket na kilka serwerów i utrzymać działanie kanałów, pub/sub oraz obecności na wszystkich z nich. Kanały mogą pamiętać swoje ostatnie wiadomości, więc klient, który się rozłączy i wróci, dostaje to, co go ominęło. Klienci łączą się ponownie z wykładniczym wycofywaniem i losowym rozrzutem, zamiast uderzać w serwer równym krokiem, kolejkę wysyłkową można ograniczyć, żeby jeden wolny odbiorca nie wyczerpał pamięci serwera, a klient HTTP zyskał zestaw zabezpieczeń przed przekierowaniami wyciekającymi poświadczenia, obniżeniem poziomu TLS i odpowiedziami bez limitu rozmiaru.
Do tego dochodzi warstwa async / await dla Delphi, gzip i deflate na serwerach HTTP, nowa metoda HTTP QUERY, weryfikacja tożsamości dla szyfrowania end-to-end, OAuth2 w kliencie MCP oraz długa lista poprawek. Ten wpis to przewodnik po całości. Każda sekcja odsyła do artykułu, który omawia daną funkcję szczegółowo.
Klastrowanie na kilku serwerach
Nowy komponent TsgcWSCluster łączy kilka serwerów sgcWebSockets w jeden serwer logiczny. Wiadomość opublikowana na węźle A dociera do subskrybentów podłączonych do węzła B, a obecność zwraca listę uczestników całego klastra, a nie tylko lokalnego węzła. Dostępne są dwa mechanizmy transportu: wbudowana siatka, w której węzły rozmawiają ze sobą bezpośrednio i nie instalujesz nic dodatkowego, oraz Redis Pub/Sub dla większych wdrożeń (Enterprise).
uses
sgcWebSocket, sgcWebSocket_Protocols, sgcWebSocket_Cluster;
oCluster := TsgcWSCluster.Create(nil);
oCluster.EngineType := clusterMesh; // no extra infrastructure
oCluster.ClusterPort := 5410; // this node's mesh listener
oCluster.Peers.Add('192.168.1.101:5410'); // the other nodes
oCluster.Attach(oProtocol); // cluster this protocol's pub/sub
oCluster.Start;
Czytaj więcej: Skalowanie serwerów WebSocket na wiele węzłów.
Historia wiadomości i odzyskiwanie po ponownym połączeniu
Serwer protokołu sgc może teraz przechowywać ostatnie N wiadomości każdego kanału, opcjonalnie z czasem życia. Gdy klient łączy się ponownie i ponawia subskrypcję, wysyła przesunięcie ostatniej wiadomości, którą faktycznie zobaczył, a serwer odtwarza wszystko, co zostało opublikowane pod jego nieobecność. W Twoim kodzie klienta nic się nie zmienia poza ponowną subskrypcją, którą i tak już wykonujesz, a cała funkcja jest wyłączona, dopóki jej nie włączysz.
oProtocol.History.Enabled := True;
oProtocol.History.Size := 1000; // last 1000 messages per channel
oProtocol.History.TTLSeconds := 3600; // optional: also expire after 1 hour
Czytaj więcej: Historia wiadomości i odzyskiwanie po ponownym połączeniu.
async / await oraz Connect, które naprawdę czeka
Nowy moduł sgcBase_AsyncAwait wnosi do biblioteki zadania i obiekty przyszłości. Możesz oczekiwać na żądanie HTTP, połączenie WebSocket albo uzupełnienie czatu AI bez podpinania choćby jednej procedury obsługi zdarzeń, połączyć wynik z ThenProc i OnError oraz anulować zadanie w sposób, który faktycznie przerywa żądanie pod spodem.
W tym samym duchu Connect blokuje teraz do czasu pełnego nawiązania połączenia, a nie tylko jego rozpoczęcia, a Disconnect czeka, aż gniazdo naprawdę się zamknie. To zamyka wyścig, który potrafił zaboleć przy szybkich ponownych połączeniach. Gdy połączenie lub wysyłka zawiedzie, powód jest dostępny w nowej właściwości LastError, a wersja przeciążona Connect zwraca tekst błędu bezpośrednio, więc możesz zdiagnozować awarię bez subskrybowania OnError.
var
vError: string;
begin
if sgcWebSocketClient1.Connect(10000) then
sgcWebSocketClient1.WriteData('hello')
else
ShowMessage('Connect failed: ' + sgcWebSocketClient1.LastError);
// or get the reason back directly from the call
if not sgcWebSocketClient1.Connect(vError, 10000) then
ShowMessage('Connect failed: ' + vError);
end;
Czytaj więcej: async / await w Delphi.
Wzmocnienie klienta HTTP
Przekierowanie to najprostszy sposób na utratę tokenu. Jeśli serwer odpowie na Twoje uwierzytelnione żądanie kodem 302 wskazującym inny host, klient ochoczo powtarza tam nagłówki Authorization i Cookie. Wersja 2026.7 dodaje StripAuthOnCrossHostRedirect, aby usuwać je przy przekierowaniu na inną witrynę, oraz NoInsecureRedirect, aby odrzucać przekierowanie obniżające HTTPS do zwykłego HTTP.
Odpowiedzi też można teraz ograniczać: MaxChunkSize dla pojedynczego fragmentu odpowiedzi porcjowanej i MaxResponseSize dla całości. RejectPublicSuffixCookies odrzuca ciasteczka przypisane do zbyt szerokich domen, takich jak "com" albo "co.uk". Przy wysyłaniu danych dostępne jest Expect: 100-continue, które pyta serwer o zgodę przed wysłaniem dużej treści, oraz porcjowana treść żądania do strumieniowania wysyłki o nieznanym jeszcze rozmiarze.
oHTTP.StripAuthOnCrossHostRedirect := True;
oHTTP.NoInsecureRedirect := True;
oHTTP.MaxResponseSize := 10 * 1024 * 1024; // 10 MB, 0 = unlimited
oHTTP.MaxChunkSize := 1024 * 1024; // 1 MB per chunk
oHTTP.RejectPublicSuffixCookies := True;
Wszystkie te przełączniki są domyślnie wyłączone i żaden z nich nie wymaga sięgania po niskopoziomowy obiekt HTTP: są opublikowane także w gotowych klientach API (AI/LLM, giełdy kryptowalut, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush). Zabezpieczenia przekierowań i rozmiaru są również w kliencie HTTP/2, a HTTP/3 zyskuje limit rozmiaru odpowiedzi. Czytaj więcej: Wzmocnienie klienta HTTP.
Ponowne próby, wycofywanie i losowy rozrzut
WatchDog łączył się ponownie w stałym odstępie, co oznacza, że tysiąc klientów, którzy stracą serwer, wraca w tej samej chwili. Teraz obsługuje wykładnicze wycofywanie z mnożnikiem, górnym pułapem i losowym rozrzutem, dzięki czemu flota rozkłada się w czasie. Stały odstęp pozostaje wartością domyślną, więc nic się nie zmienia, dopóki o to nie poprosisz.
Klient HTTP zyskał własną politykę ponawiania: ponawianie na podstawie konfigurowalnej listy kodów statusu, coraz dłuższe oczekiwanie i respektowanie wskazówki serwera Retry-After, gdy ją wyśle. Klienci OpenAI, Anthropic i Gemini także z niej korzystają.
sgcWebSocketClient1.WatchDog.Backoff := wdbExponential;
sgcWebSocketClient1.WatchDog.BackoffMultiplier := 2.0; // double every attempt
sgcWebSocketClient1.WatchDog.MaxInterval := 60; // seconds, the ceiling
sgcWebSocketClient1.WatchDog.Jitter := 0.2; // up to 20% random spread
Czytaj więcej: Wykładnicze wycofywanie, losowy rozrzut i Retry-After.
Kontrola przeciążenia kolejki wysyłkowej
Gdy klient czyta wolniej, niż Ty piszesz, wiadomości w kolejce piętrzą się w pamięci serwera. Możesz teraz ograniczyć liczbę oczekujących wiadomości na połączenie za pomocą QueueOptions.MaxQueueSize i wybrać, co dzieje się po osiągnięciu limitu: odrzucenie najstarszej wiadomości, odrzucenie najnowszej albo rozłączenie połączenia. Nowe zdarzenie OnSendBufferFull jest zgłaszane, zanim cokolwiek zostanie odrzucone, więc możesz to zalogować, policzyć albo zawetować odrzucenie dla połączenia, którego nie możesz sobie pozwolić przyciąć. Kolejka jest domyślnie nieograniczona.
oServer.QueueOptions.MaxQueueSize := 1000;
oServer.QueueOptions.OverflowPolicy := qopDropOldest; // or qopDropNewest, qopDisconnect
Czytaj więcej: Limity kolejki wysyłkowej dla wolnych klientów WebSocket.
gzip i deflate na serwerze HTTP
Serwery HTTP mogą teraz kompresować swoje odpowiedzi, gdy klient zgłasza Accept-Encoding. Dotyczy to plików serwowanych z DocumentRoot oraz odpowiedzi budowanych przez Ciebie w OnCommandGet, pomija treści poniżej minimalnego rozmiaru i typy zawartości, które i tak by się nie zmniejszyły, a dostępne jest również na serwerze HTTP.sys. Kompresja jest domyślnie wyłączona i na razie kompresowane są tylko odpowiedzi HTTP/1.1.
sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.HTTPCompression.Level := 6; // 1..9
sgcWebSocketHTTPServer1.HTTPCompression.MinSize := 1024; // bytes
Czytaj więcej: Kompresja gzip i deflate na serwerze HTTP.
Metoda HTTP QUERY
QUERY to nowa metoda HTTP opracowana przez IETF, która wysyła zapytanie w treści żądania jak POST, ale pozostaje bezpieczna i możliwa do zbuforowania jak GET, więc Twoje zapytanie nie musi się już mieścić w adresie URL o ograniczonej długości. Wersja 2026.7 implementuje ją w klientach HTTP/1.x, HTTP/2, HTTP/3 i REST, a serwery oraz proxy ją obsługują.
vResult := oClient.Query('https://api.example.org/contacts', oQuery);
Czytaj więcej: Nowa metoda HTTP QUERY w Delphi.
Weryfikacja tożsamości w E2EE
Szyfrowanie end-to-end utrzymuje ładunek w tajemnicy, ale samo w sobie nie mówi, kto jest po drugiej stronie. Serwer albo przekaźnik pośrodku może podać każdej ze stron własny klucz i czytać wszystko. W 2026.7 każda strona może podpisać swój klucz szyfrujący długoterminowym kluczem tożsamości, a druga strona weryfikuje ten podpis, więc cicha podmiana klucza zostaje wykryta, a nie zaakceptowana.
Działa to w rozmowach jeden na jeden i w czatach grupowych, dodaje zdarzenia pozwalające zatwierdzić lub przypiąć tożsamość drugiej strony oraz ostrzec Cię, gdy jej klucz tożsamości się zmieni, a całość jest domyślnie wyłączona i w pełni zgodna wstecz z uczestnikami w wersji 2026.6.
E2EE.E2EE_Options.Identity.Enabled := True;
E2EE.E2EE_Options.Identity.PrivateKey := LoadIdentityPrivateKey; // PEM
E2EE.E2EE_Options.Identity.PublicKey := LoadIdentityPublicKey; // PEM
E2EE.OnE2EEVerifyPeerIdentity := OnE2EEVerifyPeerIdentityEvent;
E2EE.OnE2EEKeyChange := OnE2EEKeyChangeEvent;
Czytaj więcej: Weryfikacja tożsamości w E2EE.
OAuth2 dla klienta MCP oraz grant Identity Assertion
Klient MCP może teraz uwierzytelniać się przez OAuth2 zamiast statycznego klucza API. Sam pobiera token, zapisuje go w pamięci podręcznej aż do wygaśnięcia i odświeża, a gdy OAuth2 jest włączone, ma pierwszeństwo przed kluczem API. Obok tego klient OAuth2 zyskuje nowy typ grantu, Identity Assertion Authorization Grant, który przenosi tożsamość z jednej domeny do drugiej: klient przeprowadza za Ciebie całą wieloetapową wymianę i zgłasza zdarzenia, dzięki czemu możesz śledzić każdy krok.
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.Enabled := True;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.GrantType := auth2ClientCredentials;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.TokenURL := 'https://auth.example.com/oauth2/token';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientId := 'YOUR_CLIENT_ID';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientSecret := 'YOUR_CLIENT_SECRET';
Czytaj więcej: OAuth2 dla klienta MCP.
Strumienie kryptowalut: ponowna subskrypcja i limitowanie żądań
Do tej pory, gdy gniazdo z danymi rynkowymi padało, a WatchDog je przywracał, gniazdo było podniesione, ale nie miałeś żadnej subskrypcji, dopóki sam nie odtworzyłeś każdej z nich. Klienci giełd mogą teraz zrobić to za Ciebie: ustaw Resubscribe := True, a Twoje strumienie zostaną przywrócone po ponownym połączeniu. Obejmuje to Binance, Kraken, Coinbase i około czternastu innych giełd, a także oparty na sesji strumień XTB. Domyślnie ma wartość False.
Klienci REST API zyskują opcjonalny limiter żądań po stronie klienta, dzięki czemu seria żądań nie skończy się czasowym banem od giełdy. Ogranicz liczbę żądań wysyłanych w oknie czasowym i wybierz, czy nadmiarowe żądanie ma czekać, czy zostać odrzucone. Domyślnie wyłączony.
oBinance.RateLimit.Enabled := True;
oBinance.RateLimit.IntervalMs := 60000; // one minute window
oBinance.RateLimit.MaxRequests := 1000;
oBinance.RateLimit.Behavior := rlbWait;
Czytaj więcej: Ponowna subskrypcja i limiter po stronie klienta.
Mniejsze dodatki
- Ustawienie wstępne TLS. Każdy obiekt opcji TLS publikuje teraz właściwość
Preset. UstawienieTLSOptions.Preset := tlspSecureDefaultswłącza jedną linią weryfikację certyfikatu, TLS 1.2 lub nowszy oraz sprawdzanie nazwy hosta. Wartość domyślna,tlspCustom, pozostawia Twoje obecne ustawienia nietknięte. - Własna klasa sesji HTTP. Przypisz własnego potomka
TIdHTTPSessiondo właściwościSessionClassserwera HTTP przed jego uruchomieniem, a będziesz mógł przechowywać własne dane wewnątrz sesji, podczas gdy identyfikator sesji, ciasteczko, limit czasu i czyszczenie działają dokładnie tak jak wcześniej. Jeśli potrzebujesz pełnej kontroli nad tym, gdzie żyją sesje, możesz przypisać także własnąSessionList. - Funkcje pomocnicze certyfikatów RFC 2253. Nowe funkcje odczytują podmiot i wystawcę certyfikatu jako standardowy ciąg nazwy wyróżniającej zgodny z RFC 2253.
- Klient WebSocket WinHTTP. Obsługuje teraz logowanie tokenem/bearer i przez URL tak jak standardowy klient, udostępnia zdarzenie
OnHandshake, dzięki czemu możesz dodać własne nagłówki do żądania połączenia, i potrafi zapisywać plik dziennika rejestrujący połączenia, rozłączenia oraz każdą wysłaną i odebraną wiadomość tekstową i binarną. Logowanie OAuth2, JWT i sesyjne nadal jest tam niedostępne, ponieważ klient korzysta z wbudowanego stosu sieciowego Windows i nie zawiera Indy.
Poprawki i wzmocnienia
2026.7 niesie długą listę poprawek. Zamiast wymieniać wszystkie, oto do czego się sumują.
Bezpieczeństwo pamięci i wzmocnienie parserów. Odczyty poza końcem bufora zostały naprawione w kliencie MQTT 5 (broker deklarujący więcej danych, niż wysłał), kliencie AMQP 1.0 (dekodowanie UUID), parserze STUN/TURN (w tym nieskończona pętla i adresy IPv6), kanale danych SCTP w WebRTC oraz w skanerze ramek surowego TCP. Klient i serwer UDP, w tym DTLS, nie zwalniają już gniazda dwukrotnie ani nie pozostawiają go wiszącego przy rozłączeniu. Dodano wewnętrzne limity tam, gdzie źle zachowujący się partner mógł w przeciwnym razie rozdymać pamięć bez ograniczeń: kolejka oczekujących wiadomości MQTT, subskrypcje protokołu sgc na połączenie, oczekujące wywołania serwera WAMP, linie zakończeniowe odpowiedzi porcjowanej oraz głębokość zagnieżdżenia tablic pól AMQP.
HTTP/2. Limit rozmiaru po dekompresji (domyślnie 64 MB) zamyka dziurę prowadzącą do wyczerpania pamięci przy odpowiedziach typu "bomba zip", limitu rozmiaru odpowiedzi nie da się już obejść ostatnią częścią odpowiedzi, a nieudane żądanie kończy się natychmiast, zamiast czekać do końca limitu czasu.
Kryptografia i losowość. Serwer WebAuthn, serwer autoryzacji OAuth2 i wbudowane identyfikatory sesji HTTP korzystają teraz z kryptograficznie bezpiecznego generatora liczb losowych, wyzwania są jednorazowe, a sekrety porównywane w stałym czasie (sekret klienta, podpis JWT, hasło Basic w HTTP API). JWT z prawidłowym podpisem, ale błędnym roszczeniem, jest teraz odrzucany zamiast akceptowany. Przy włączonym StrictVerify w OpenSSL certyfikat jest sprawdzany także względem nazwy hosta, więc prawidłowy certyfikat wystawiony dla innego hosta zostaje odrzucony. Nie dotyczy to połączeń pod adres IP ani istniejących ustawień.
Server-Sent Events. Strumieniowana odpowiedź, która dostarczała kilka zdarzeń w jednym odczycie, albo zdarzenie rozdzielone na dwa odczyty, traciła wszystko poza pierwszym. Zostało to naprawione, co przywraca strumieniowanie token po tokenie w klientach AI/LLM. Strumieniowany czat OpenAI nie ustawiał też flagi strumienia, więc teraz strumieniuje tak jak pozostali dostawcy.
Klienci giełd. Identyfikatory żądań Kraken są teraz ściśle rosnące, BitMEX wysyła czas wygaśnięcia w sekundach zamiast w milisekundach, MEXC podpisuje zakodowane parametry, które faktycznie wysyła, Cryptorobotics nie zamienia już miejscami dwóch wartości w wywołaniach po skrócie, Deribit odświeża token logowania przed jego wygaśnięciem, a klient Forex zgłasza błąd, który wcześniej połykał podczas odczytu identyfikatora konta.
Lazarus i Free Pascal. Trzy poprawki kompilacji: interfejsy w module JSON używają teraz właściwej konwencji wywołania dla danej platformy (nie kompilowały się na Linuksie), klient Forex nie wywołuje już funkcji dostępnej tylko w Delphi do odczytu formatu liczb, a moduł postkwantowej wymiany kluczy nie zależy już od size_t.
Więcej znajdziesz w history.txt, w tym klienta gRPC (równoległe wywołania mogły odbierać nawzajem swoje odpowiedzi, a nieudana wysyłka była raportowana jako sukces), serwer OpenAPI (wczytywanie specyfikacji jest teraz bezpieczne wątkowo, a Twoje procedury obsługi nie działają już, gdy trzymana jest wewnętrzna blokada), wyciek połączenia i gniazda na serwerze przy każdym nieudanym logowaniu, awarię przy odpowiedziach OpenAI bez pola "message", takich jak te z Ollama i LM Studio, naprawione WriteAndWaitData w kliencie WinHTTP oraz ukrywanie sekretów w dzienniku klienta HTTP, dzięki czemu włączenie logowania nie zapisuje już tokenów na dysk otwartym tekstem.
Edycja .NET
sgcWebSockets .NET 2026.7 skupia się na kliencie HTTP. Dostarcza ten sam zestaw zabezpieczeń co edycja Delphi: usuwanie poświadczeń przy przekierowaniu na inną witrynę, blokadę obniżenia HTTPS do HTTP, limity rozmiaru pojedynczego fragmentu i całej odpowiedzi, odrzucanie ciasteczek z sufiksem publicznym, Expect: 100-continue oraz porcjowane treści żądań. Są one dostępne w komponentach klienta HTTP i w gotowych klientach API (klienci AI/LLM, OAuth2, Google Cloud, WhatsApp, AWS SQS, WebPush), a te same zabezpieczenia przekierowań i rozmiaru są w kliencie HTTP/2. Dołączone są także poprawki obsługi przekierowań i wygasania ciasteczek. Wszystko jest domyślnie wyłączone.
Aktualizacja
2026.7 to aktualizacja typu drop-in dla istniejących projektów 2026.x. Każda nowa funkcja w tym wydaniu jest domyślnie wyłączona: klastrowanie, historia wiadomości, wycofywanie, limit kolejki wysyłkowej, kompresja HTTP, zabezpieczenia klienta, weryfikacja tożsamości E2EE i ponowna subskrypcja na giełdach muszą zostać włączone jawnie, więc instalacja nowej kompilacji nie zmienia żadnego zachowania, dopóki sam się nie zdecydujesz.
Klienci z aktywną subskrypcją mogą pobrać nową kompilację ze strefy klienta albo z esegece.com/products/websockets/download.
Pytania, opinie albo pomoc przy migracji? Skontaktuj się z nami. Odpowiedź otrzymasz od osób, które napisały ten kod.
