Skip to content

fix: allow session recovery even if no event was received - #5541

Open
marwan562 wants to merge 1 commit into
socketio:mainfrom
marwan562:fix/5538-zero-event-recovery
Open

fix: allow session recovery even if no event was received#5541
marwan562 wants to merge 1 commit into
socketio:mainfrom
marwan562:fix/5538-zero-event-recovery

Conversation

@marwan562

Copy link
Copy Markdown

The kind of change this PR does introduce

  • a bug fix

Current behavior

When connectionStateRecovery is enabled, a client that connects, joins rooms, and disconnects before the server emits any events cannot recover its session on reconnection (socket.recovered is false, a new socket.id is generated, room memberships and socket.data are lost).

This happens because _lastOffset is only set on the client when an EVENT packet is received. In the "zero-event" case, the reconnect CONNECT packet contains no offset at all ({"pid":"..."}), and the server-side check in namespace.ts:

if (
  this.server.opts.connectionStateRecovery &&
  typeof sessionId === "string" &&
  typeof offset === "string"
) {

skips restoreSession() entirely.

New behavior

The offset is now optional in Adapter#restoreSession():

  • in namespace.ts, a non-string offset is normalized to undefined, and recovery is attempted as long as a valid private session id (pid) is provided
  • in SessionAwareAdapter#restoreSession(), an undefined offset means the client did not receive any event yet, so the session (id, rooms, data) is restored without replaying any event

Note for external adapters (Redis adapter, Postgres adapter, cluster adapters...): restoreSession() may now be called with offset === undefined. Implementations that don't handle it can keep their current signature; returning null preserves the previous behavior.

Other information (e.g. related issues)

Fixes #5538

Testing:

  • added 2 cases in the server raw-packet suite (test/connection-state-recovery.ts): zero-event recovery (id/rooms/data restored, no replayed events) and recovery with a non-string offset
  • added 1 case in packages/socket.io-adapter/test/index.ts: restore with an undefined offset returns the session with an empty missedPackets array
  • added 1 end-to-end case in packages/socket.io-client/test/connection-state-recovery.ts: real client reconnects with recovered === true without any prior event
  • all suites pass locally: npm test -w packages/socket.io (217 passing), adapter suite (22 passing), client node suite (112 passing; one pre-existing flaky failure in the unrelated autoUnref child-process test, which also fails on a clean checkout)

Before that fix, the session could only be recovered if the client
provided the offset of the last event it had received. But when no
event was received before the disconnection, the offset was undefined,
which prevented the restoration of the session (id, rooms and data).

The offset is now optional in Adapter#restoreSession: when it is not
provided, the session is restored without replaying any event.

Fixes socketio#5538
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connection State Recovery fails if client reconnects before server emits any events ("Zero-Event" reconnect)

1 participant