A renewed STOMP subscription resumes live delivery; it does not reconstruct messages sent while the browser was disconnected.
Spring WebSocket reconnect: recover state after an unobserved gap
Detect the gap
A dashboard receives stock version 84, loses its socket, and reconnects when the current version is 91. Subscribing again may receive only version 92 onward. The browser must fetch a snapshot or request durable events after 84 before declaring itself current. The version belongs to the business data, not to the WebSocket frame transport. An external broker improves cross-node routing but does not by itself define offline replay.
Order snapshot and stream
One approach subscribes first, then requests a snapshot and discards live frames at or below the snapshot version. Another obtains a snapshot with a resumable cursor and then subscribes from that cursor if the broker supports it. Either way, define duplicate handling, tenant scope, and what happens when the cursor is too old. Destination authorization must be checked for both the socket and the snapshot HTTP endpoint.
Test with a deliberate disconnect
Publish versions 84 through 91 while the browser is offline. Reconnect through a different application instance. Assert the client ends at version 91 or later without applying an older update after a newer one. Simulate a missing version and force a fresh snapshot. The client pseudocode captures the ordering rule; a browser and broker integration test remains necessary.
Implementation sketch
if (incoming.version() <= currentVersion) return;
if (incoming.version() != currentVersion + 1) {
requestFreshSnapshot();
return;
}
applyStockUpdate(incoming);
currentVersion = incoming.version();Cost and verification
Snapshots add one read on reconnect; durable replay adds storage and cursor management. Either is cheaper than silently displaying a wrong stock count after a network gap.
Common Mistakes
- Do not assume a new SUBSCRIBE replays frames sent during disconnection.
- Do not apply an older frame after a newer snapshot.
- Do not expose another tenant's snapshot through a cursor or destination name.
Read next
Spring STOMP simple broker versus relay: the multi-instance boundary, Spring STOMP broker relay: credentials and broker availability are separate from user identity, Spring WebSocket STOMP identity: authenticate the handshake, authorize destinations, Spring GraphQL tenant reads: scope every resolver before returning a record.
