diff --git a/lib/socket.ts b/lib/socket.ts index ba82fa2b88..59138cfe9e 100644 --- a/lib/socket.ts +++ b/lib/socket.ts @@ -217,6 +217,22 @@ export class Socket< * }); */ public connected: boolean = false; + /** + * The identifier of the current packet. Multiple retries of the same packet will have the same identifier, in order + * to allow deduplication (only process a packet once). + * + * @example + * io.on("connection", (socket) => { + * socket.on("my-event", async (payload, callback) => { + * const offset = socket.currentOffset; + * + * await insertInDatabase(payload, offset); + * + * callback(); + * }) + * }); + */ + public currentOffset: string; /** * The session ID, which must not be shared (unlike {@link id}). @@ -652,6 +668,7 @@ export class Socket< if (null != packet.id) { debug("attaching ack callback to event"); args.push(this.ack(packet.id)); + this.currentOffset = `${this.id}-${packet.id}`; } if (this._anyListeners && this._anyListeners.length) { diff --git a/test/socket.ts b/test/socket.ts index 94613c53cf..4c7b784065 100644 --- a/test/socket.ts +++ b/test/socket.ts @@ -1105,4 +1105,28 @@ describe("socket", () => { socket3.on("disconnect", partialDone); }); }); + + // TODO: enable once a new version of the socket.io-client package is released + // it("should retry with the same packet ID", (done) => { + // const io = new Server(0); + // let counter = 0; + // + // io.on("connection", (socket) => { + // socket.on("my-event", (cb) => { + // expect(socket.currentOffset).to.eql(socket.id + "-0"); + // if (++counter === 3) { + // cb(); + // + // success(done, io, clientSocket); + // } + // }); + // }); + // + // const clientSocket = createClient(io, "/", { + // retries: 10, + // ackTimeout: 20, + // }); + // + // clientSocket.emit("my-event"); + // }); });