Echte WebSocket-Clients verlieren ständig ihre Verbindung: ein Telefon wird gesperrt, das WLAN wechselt zu Mobilfunk, ein Tunnel stockt, ein Captive Portal kommt dazwischen. Wenn die Verbindung zurückkehrt, sind die Nachrichten, die während der Abwesenheit des Clients veröffentlicht wurden, verloren. "Ich habe Nachrichten verpasst, während mein Telefon gesperrt war" ist der Fehler, den Benutzer zuerst bemerken, und die übliche Behelfslösung — bei jedem Reconnect den gesamten Zustand erneut abzurufen — ist verschwenderisch und leicht falsch umzusetzen.
sgcWebSockets löst dies jetzt direkt. Aktivieren Sie den Verlauf auf dem Server, und ein Client, der sich erneut verbindet, holt genau die Nachrichten nach, die er verpasst hat, anhand des Offsets. Es ist optional und standardmäßig deaktiviert, sodass bestehende Deployments sich genau wie bisher verhalten, bis Sie es einschalten. Dieser Beitrag behandelt die Funktionsweise, die Konfiguration sowie Delphi- und .NET-Beispiele.
So funktioniert es
Wenn der Verlauf aktiviert ist, wird jede an einen Kanal veröffentlichte Nachricht mit einem monoton steigenden Offset versehen und an einen begrenzten Ringpuffer pro Kanal auf dem Server angehängt. Der Client merkt sich den letzten Offset, den er auf jedem Kanal empfangen hat. Wenn er sich erneut verbindet und neu abonniert, sendet er diesen Offset, und der Server holt jede neuere Nachricht für genau diese eine Verbindung nach — in der richtigen Reihenfolge, ohne Duplikate.
Der Client trägt den Offset, sodass keine serverseitige Sitzung zu verwalten ist. Die Wiederherstellung ist einfach ein normales erneutes Abonnieren.
Verlauf auf dem Server aktivieren
Der Verlauf befindet sich auf dem sgc-Protokollserver, unter einem History-Optionsobjekt. Schalten Sie ihn ein und begrenzen Sie ihn nach Nachrichtenanzahl und / oder Alter:
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 begrenzt den Speicher pro Kanal (es begrenzt auch das, was früher eine unbegrenzte Warteschlange war); TTLSeconds ist eine optionale Altersgrenze. Bei deaktiviertem Verlauf (Standard) gibt es keinen Offset auf der Leitung und überhaupt keine Verhaltensänderung.
Automatische Wiederherstellung auf dem Client
Der Client verfolgt die Offsets für Sie. Nach einem Reconnect fordert ein einfaches Subscribe den Server automatisch auf, alles Verpasste auf diesem Kanal nachzuholen — Sie müssen nichts verfolgen oder übergeben:
// 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);
Die Offset-Zuordnung pro Kanal überlebt einen Disconnect, sodass erneutes Verbinden und Abonnieren alles ist, was nötig ist. GetLastOffset('news') macht den Cursor verfügbar, falls Sie ihn anzeigen oder persistieren möchten.
.NET
Die verwaltete Edition spiegelt die API. Aktivieren Sie den Verlauf auf dem Serverprotokoll, und der Client stellt sich beim erneuten Abonnieren wieder her:
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");
Optional und standardmäßig sicher
Der Verlauf ist standardmäßig deaktiviert. Wenn er deaktiviert ist, tragen veröffentlichte Frames keinen Offset, und die Publish- / Subscribe-Pfade sind Byte für Byte das, was sie vorher waren — ein Upgrade ändert also nichts, bis Sie es ausdrücklich aktivieren. Wenn Sie es aktivieren, hält der begrenzte Ring den Speicherbedarf vorhersehbar.
In einem Cluster mit mehreren Knoten ist der Verlauf in dieser Version knotenlokal: ein Client, der sich erneut mit demselben Knoten verbindet, erhält die vollständige Wiederholung. Ein gemeinsamer clusterweiter Verlauf steht auf der Roadmap. Eine sofort lauffähige Demo wird mit der Bibliothek ausgeliefert (02.WebSocket_Protocols\15.MessageHistory_Recovery bei Delphi, samples\HistoryRecoveryDemo bei .NET): sie nimmt einen Client offline, veröffentlicht während seiner Abwesenheit, verbindet ihn erneut und zeigt, wie er genau die Nachrichten wiederherstellt, die er verpasst hat.
Verfügbarkeit
Nachrichtenverlauf und Wiederherstellung nach Reconnect sind auf dem sgc-Protokoll über Delphi 7 bis 13 (Win32/Win64, Linux64, macOS, Android und iOS) sowie auf der verwalteten .NET-Edition verfügbar. Es passt natürlich zur WatchDog-Auto-Reconnect-Funktion, die sgcWebSockets-Clients bereits besitzen.
Kunden mit einem aktiven Abonnement können den neuen Build im Kundenbereich herunterladen. Testbenutzer können den aktualisierten Installer unter esegece.com/products/websockets/download herunterladen.
Fragen, Feedback oder Hilfe beim Einbinden der Wiederherstellung in Ihre App? Kontaktieren Sie uns — Sie erhalten eine Antwort von den Leuten, die den Code geschrieben haben.
