Rzeczywiści klienci WebSocket nieustannie tracą połączenie: telefon się blokuje, Wi-Fi przełącza się na sieć komórkową, tunel ma czkawkę, na drodze staje portal przechwytujący. Gdy połączenie wraca, wiadomości opublikowane w czasie, gdy klient był nieobecny, przepadają. "Przegapiłem wiadomości, gdy mój telefon był zablokowany" to awaria, którą użytkownicy zauważają jako pierwszą, a zwykłe obejście — ponowne pobranie całego stanu przy każdym ponownym połączeniu — jest marnotrawne i łatwo je popsuć.
sgcWebSockets rozwiązuje to teraz bezpośrednio. Włącz historię na serwerze, a klient, który ponownie się połączy, automatycznie odtwarza dokładnie te wiadomości, które pominął, według offsetu. Jest to opcjonalne i domyślnie wyłączone, więc istniejące wdrożenia zachowują się dokładnie tak jak wcześniej, dopóki tego nie włączysz. Ten wpis opisuje, jak to działa, konfigurację oraz przykłady w Delphi i .NET.
Jak to działa
Gdy historia jest włączona, każda wiadomość opublikowana na kanale jest oznaczana monotonicznie rosnącym offsetem i dołączana do ograniczonego bufora cyklicznego dla danego kanału na serwerze. Klient zapamiętuje ostatni offset otrzymany na każdym kanale. Gdy ponownie się połączy i ponownie subskrybuje, wysyła ten offset, a serwer odtwarza każdą nowszą wiadomość do tego jednego połączenia — w kolejności, bez duplikatów.
Offset przenosi klient, więc nie ma sesji po stronie serwera, którą trzeba zarządzać. Odzyskiwanie to po prostu zwykła ponowna subskrypcja.
Włączanie historii na serwerze
Historia znajduje się na serwerze protokołu sgc, w obiekcie opcji History. Włącz ją i ogranicz liczbą wiadomości i / lub wiekiem:
uses
sgcWebSocket, sgcWebSocket_Protocols;
var
oProtocol: TsgcWSPServer_sgc;
begin
oProtocol := TsgcWSPServer_sgc.Create(nil);
oProtocol.Server := oServer;
oProtocol.History.Enabled := True;
oProtocol.History.Size := 1000; // keep the last 1000 messages per channel
oProtocol.History.TTLSeconds := 3600; // optional: also drop entries older than 1 hour
end;
Size ogranicza pamięć na kanał (ogranicza także to, co kiedyś było nieograniczoną kolejką); TTLSeconds to opcjonalny limit wieku. Przy wyłączonej historii (domyślnie) nie ma offsetu w transmisji ani żadnej zmiany zachowania.
Automatyczne odzyskiwanie na kliencie
Klient śledzi offsety za Ciebie. Po ponownym połączeniu zwykłe Subscribe automatycznie prosi serwer o odtworzenie wszystkiego, co pominięto na danym kanale — nie musisz niczego śledzić ani przekazywać:
// On (re)connect, just resubscribe. The client auto-sends the last offset it saw,
// and the server replays the messages published while the client was offline.
sgcWSPClient_sgc1.Subscribe('news');
// Or request the full retained history explicitly (cursor 0 = everything kept):
sgcWSPClient_sgc1.Subscribe('news', 0);
Mapa offsetów dla poszczególnych kanałów przetrwa rozłączenie, więc wystarczy ponowne połączenie i ponowna subskrypcja. GetLastOffset('news') udostępnia kursor, jeśli chcesz go wyświetlić lub zapisać.
.NET
Edycja zarządzana odzwierciedla to API. Włącz historię na protokole serwera, a klient odzyska dane przy ponownej subskrypcji:
var protocol = new TsgcWSPServer_sgc { Server = server };
protocol.History.Enabled = true;
protocol.History.Size = 1000;
protocol.History.TtlSeconds = 3600;
// Client: a plain resubscribe after reconnect recovers the missed messages.
client.Subscribe("news");
long last = client.GetLastOffset("news");
Opcjonalne i bezpieczne domyślnie
Historia jest domyślnie wyłączona. Gdy jest wyłączona, opublikowane ramki nie zawierają offsetu, a ścieżki publikowania / subskrypcji są bajt w bajt takie same jak wcześniej — więc aktualizacja niczego nie zmienia, dopóki jej jawnie nie włączysz. Gdy ją włączysz, ograniczony bufor cykliczny utrzymuje przewidywalne zużycie pamięci.
W klastrze wielowęzłowym historia jest w tym wydaniu lokalna dla węzła: klient, który ponownie połączy się z tym samym węzłem, otrzymuje pełne odtworzenie. Współdzielona historia obejmująca cały klaster jest w planach. Z biblioteką dostarczane jest gotowe do uruchomienia demo (02.WebSocket_Protocols\15.MessageHistory_Recovery w Delphi, samples\HistoryRecoveryDemo w .NET): odłącza klienta od sieci, publikuje, gdy jest on nieobecny, ponownie go łączy i pokazuje, że odzyskuje dokładnie te wiadomości, które pominął.
Dostępność
Historia wiadomości i odzyskiwanie po ponownym połączeniu są dostępne na protokole sgc w Delphi od 7 do 13 (Win32/Win64, Linux64, macOS, Android i iOS) oraz w zarządzanej edycji .NET. Naturalnie współgra to z automatycznym ponownym połączeniem WatchDog, które klienci sgcWebSockets już mają.
Klienci z aktywną subskrypcją mogą pobrać nową kompilację ze strefy klienta. Użytkownicy wersji próbnej mogą pobrać zaktualizowany instalator pod adresem esegece.com/products/websockets/download.
Pytania, opinie lub pomoc w podpięciu odzyskiwania do Twojej aplikacji? Skontaktuj się z nami — otrzymasz odpowiedź od osób, które napisały ten kod.
