Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#5,538 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

@marwan562 ci sta già lavorando.

Dal 23/8/2026.

  • #5541 di @marwan562 — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
56/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
javascript, node.js, typescript

Direzione di ricerca

Inizia dal gate di ripristino in socket.io/lib/namespace.ts e segui il modo in cui socket.io-client mantiene _lastOffset e invia l’handshake di riconnessione. Confronta il percorso senza eventi con restoreSession() e con il comportamento esistente di ripristino dello stato della connessione. Il lavoro è completato quando una riconnessione senza eventi precedenti conserva l’ID della sessione, le stanze e i dati, e segnala socket.recovered come true.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

enhancement

Describe the bug
When connectionStateRecovery is enabled, a client that connects, joins rooms, and disconnects before the server emits any events cannot recover its session on reconnection.

Even if the client reconnects within maxDisconnectionDuration, socket.recovered evaluates to false, a new socket.id is generated, and room memberships / socket.data are lost. This happens because _lastOffset on the client is undefined in the zero event case, causing the server's typeof offset === "string" check in namespace.ts to fail and bypass restoreSession().

To Reproduce

Socket.IO server version: 4.8.1

Server

import { Server } from "socket.io";

const io = new Server(3000, {
  connectionStateRecovery: {
    maxDisconnectionDuration: 2 * 60 * 1000,
  },
});

io.on("connection", async (socket) => {
  if (socket.recovered) {
    console.log(`RECOVERED: ${socket.id} (rooms: ${Array.from(socket.rooms).join(", ")})`);
    return;
  }

  console.log(`INITIAL CONNECT: ${socket.id}`);
  await socket.join("room:alerts");
  // Deliberately no events emitted to the client
});

Socket.IO client version: 4.8.1

Client

import { io } from "socket.io-client";

const socket = io("http://localhost:3000", {
  reconnection: true,
});

socket.on("connect", () => {
  console.log(`connect ${socket.id} (recovered: ${socket.recovered})`);

  // Simulate a brief network drop shortly after connecting
  setTimeout(() => {
    socket.io.engine.close();
  }, 200);
});

Expected behavior
When the client reconnects after the transient drop, the server should recognize the pid, restore the previous session (socket.id, room memberships, socket.data), and set socket.recovered = true.

Platform:

  • Device: PC / Mac / Server
  • OS: Linux / macOS / Windows
  • Node.js version: 20.x / 22.x

Additional context

  • Root Cause: In socket.io-client, _lastOffset remains undefined until a packet of type EVENT with an offset is received. On reconnect, the handshake sends { pid: "<id>", offset: undefined }. In socket.io/lib/namespace.ts, recovery is gated by:

    if (
      this.server.opts.connectionStateRecovery &&
      typeof sessionId === "string" &&
      typeof offset === "string"
    ) {
      session = await this.adapter.restoreSession(sessionId, offset);
    }
    

    Because offset is undefined, restoreSession() is skipped entirely despite having a valid active pid.

  • Impact: Quiet subscriber channels (e.g. alert rooms, idle game lobbies) lose session state on brief network blips unless application code manually emits a synthetic dummy event on first connect to "prime" _lastOffset.

  • Potential Solutions:

    1. Include the current server stream offset in the initial CONNECT (packet type 0) handshake payload alongside { sid, pid } so _lastOffset is initialized at connection time.
    2. Allow restoreSession(sessionId, offset) to run when offset is undefined, restoring id, rooms, and data without replaying events.
Lingua principale
TypeScript
Stelle
63.2k
Fork
10.3k
Merge medio
3h 24m
PR unite (30g)
1

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di socketio/socket.io

Tutte le issue di socketio/socket.io

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.