Real-Time Patterns and ArchitectureLesson 5.2
How to handle missed messages during WebSocket reconnection
message sequence numbers, last-seen sequence ID, catch-up on reconnect, server-side message buffer, cursor-based resume, event sourcing for WebSocket, offline queue
Connections Drop - Messages Get Lost
When a WebSocket reconnects, the client does not automatically receive messages sent during the disconnection. Fix this with sequence numbers:
// Server: attach a sequence number to every message
let seq = 0;
const buffer = []; // ring buffer, keep last N messages
function broadcast(event, data) {
const msg = { seq: ++seq, event, data };
buffer.push(msg);
if (buffer.length > 500) buffer.shift(); // keep last 500
io.emit('msg', msg);
}
// Client sends its last known seq on reconnect
socket.on('reconnect', () => {
socket.emit('catch:up', { lastSeq: lastSeenSeq });
});
// Server replays missing messages
socket.on('catch:up', ({ lastSeq }) => {
const missed = buffer.filter(m => m.seq > lastSeq);
missed.forEach(m => socket.emit('msg', m));
});This works for transient disconnections under a few minutes. For longer outages, redirect to a REST endpoint to load missed state from the database rather than relying on an in-memory buffer. Always handle the case where lastSeq is behind the oldest buffered message - in that case, send a full state refresh instead of a partial replay.
