From a82590c276aa60de5374f831a2d300a11ba9e812 Mon Sep 17 00:00:00 2001 From: KrakenTyio Date: Fri, 21 Nov 2025 09:59:17 +0100 Subject: [PATCH 1/2] Modify missedPackets to include entry ID restore messages contain actual entry ID to correct client offset --- lib/adapter.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/adapter.ts b/lib/adapter.ts index 17f082a..773d64b 100644 --- a/lib/adapter.ts +++ b/lib/adapter.ts @@ -293,8 +293,10 @@ class RedisStreamsAdapter extends ClusterAdapterWithHeartbeat { // @ts-ignore if (shouldIncludePacket(session.rooms, message.data.opts)) { + const packetData = message.data.packet.data.slice(); + packetData.push(entry.id); // @ts-ignore - session.missedPackets.push(message.data.packet.data); + session.missedPackets.push(packetData); } } offset = entry.id; From af8d6443a8560cfda29fa6da660d6d97f99862d2 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Tue, 25 Nov 2025 10:45:49 +0100 Subject: [PATCH 2/2] test: add test --- lib/adapter.ts | 16 ++++++++-------- test/connection-state-recovery.ts | 12 ++++++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/adapter.ts b/lib/adapter.ts index 773d64b..ceeffdc 100644 --- a/lib/adapter.ts +++ b/lib/adapter.ts @@ -289,14 +289,14 @@ class RedisStreamsAdapter extends ClusterAdapterWithHeartbeat { for (const entry of entries) { if (entry.message.nsp === this.nsp.name && entry.message.type === "3") { - const message = RedisStreamsAdapter.decode(entry.message); - - // @ts-ignore - if (shouldIncludePacket(session.rooms, message.data.opts)) { - const packetData = message.data.packet.data.slice(); - packetData.push(entry.id); - // @ts-ignore - session.missedPackets.push(packetData); + const message = RedisStreamsAdapter.decode(entry.message) as { + data: any; + }; + const { packet, opts } = message.data; + + if (shouldIncludePacket(session.rooms, opts)) { + packet.data.push(entry.id); + session.missedPackets.push(packet.data); } } offset = entry.id; diff --git a/test/connection-state-recovery.ts b/test/connection-state-recovery.ts index ee9eecc..6f9b643 100644 --- a/test/connection-state-recovery.ts +++ b/test/connection-state-recovery.ts @@ -1,10 +1,10 @@ import { Server } from "socket.io"; import { io as ioc } from "socket.io-client"; -import { setup, sleep } from "./util"; +import { setup } from "./util"; import expect = require("expect.js"); describe("connection state recovery", () => { - let servers: Server[], ports: number[], cleanup; + let servers: Server[], ports: number[], cleanup: () => void; beforeEach(async () => { const testContext = await setup({ @@ -82,10 +82,14 @@ describe("connection state recovery", () => { socket.io.engine.close(); socket.on("connect", () => { + // @ts-expect-error _lastOffset is private + offsets.add(socket._lastOffset); + expect(socket.recovered).to.eql(true); setTimeout(() => { expect(events).to.eql([1, 2, 3]); + expect(offsets.size).to.eql(4); socket.disconnect(); done(); @@ -94,9 +98,13 @@ describe("connection state recovery", () => { }); const events: number[] = []; + const offsets = new Set(); socket.on("myEvent", (val) => { events.push(val); + // note: the offset is updated after the callback execution + // @ts-expect-error _lastOffset is private + offsets.add(socket._lastOffset); }); });