Real WebSocket clients drop their connection all the time: a phone locks, Wi-Fi hands off to cellular, a tunnel hiccups, a captive portal gets in the way. When the connection comes back, the messages published while the client was away are gone. "I missed messages while my phone was locked" is the failure users notice first, and the usual workaround — re-fetch the entire state on every reconnect — is wasteful and easy to get wrong.
sgcWebSockets now solves this directly. Enable history on the server and a client that reconnects automatically replays exactly the messages it missed, by offset. It is opt-in and off by default, so existing deployments behave exactly as before until you turn it on. This post covers how it works, the configuration, and Delphi and .NET examples.
How it works
When history is enabled, every message published to a channel is stamped with a monotonically increasing offset and appended to a bounded per-channel ring buffer on the server. The client remembers the last offset it received on each channel. When it reconnects and resubscribes, it sends that offset, and the server replays every newer message to that one connection — in order, nothing duplicated.
The client carries the offset, so there is no server-side session to manage. Recovery is just a normal resubscribe.
Enabling history on the server
History lives on the sgc protocol server, under a History options object. Turn it on and bound it by message count and / or age:
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 caps memory per channel (it also bounds what used to be an unbounded queue); TTLSeconds is an optional age limit. With history disabled (the default) there is no offset on the wire and no behavioural change at all.
Automatic recovery on the client
The client tracks offsets for you. After a reconnect, a plain Subscribe automatically asks the server to replay anything missed on that channel — you do not have to track or pass anything:
// 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);
The per-channel offset map survives a disconnect, so reconnect-and-resubscribe is all it takes. GetLastOffset('news') exposes the cursor if you want to display or persist it.
.NET
The managed edition mirrors the API. Enable history on the server protocol, and the client recovers on resubscribe:
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");
Opt-in and safe by default
History is off by default. When it is off, published frames carry no offset and the publish / subscribe paths are byte-for-byte what they were before — so upgrading changes nothing until you explicitly enable it. When you do enable it, the bounded ring keeps memory predictable.
In a multi-node cluster the history is node-local in this release: a client that reconnects to the same node gets full replay. A shared cluster-wide history is on the roadmap. A ready-to-run demo ships with the library (02.WebSocket_Protocols\15.MessageHistory_Recovery on Delphi, samples\HistoryRecoveryDemo on .NET): it takes a client offline, publishes while it is away, reconnects it, and shows it recover exactly the messages it missed.
Availability
Message history and reconnect recovery are available on the sgc protocol across Delphi 7 through 13 (Win32/Win64, Linux64, macOS, Android and iOS) and on the managed .NET edition. It pairs naturally with the WatchDog auto-reconnect that sgcWebSockets clients already have.
Customers with an active subscription can download the new build from the customer area. Trial users can grab the updated installer at esegece.com/products/websockets/download.
Questions, feedback or help wiring recovery into your app? Get in touch — you will get a reply from the people who wrote the code.
