From cd32f02470d44d860479f9d483829a02c4321b53 Mon Sep 17 00:00:00 2001 From: Ankit Silwal Date: Sun, 25 Oct 2026 23:52:42 +0530 Subject: [PATCH] Allow socketsJoin/socketsLeave/disconnectSockets to return Promise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the return types of addSockets, delSockets, and disconnectSockets in the base Adapter from void to void | Promise so adapters (like the Redis adapter) can return Promises that resolve once all remote nodes have processed the operation. Update BroadcastOperator's socketsJoin, socketsLeave, and disconnectSockets to propagate the adapter's return value, enabling: await io.in(socketId).socketsJoin(room); This is fully backward compatible — existing code that doesn't await continues to work unchanged, while multi-server setups with async adapters can now await to ensure ordering guarantees. Related: socketio/socket.io#4734 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../socket.io-adapter/lib/in-memory-adapter.ts | 15 ++++++++++++--- packages/socket.io/lib/broadcast-operator.ts | 16 ++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/socket.io-adapter/lib/in-memory-adapter.ts b/packages/socket.io-adapter/lib/in-memory-adapter.ts index cf178170e0..ee2a4d1a3f 100644 --- a/packages/socket.io-adapter/lib/in-memory-adapter.ts +++ b/packages/socket.io-adapter/lib/in-memory-adapter.ts @@ -300,7 +300,10 @@ export class Adapter extends EventEmitter { * @param opts - the filters to apply * @param rooms - the rooms to join */ - public addSockets(opts: BroadcastOptions, rooms: Room[]): void { + public addSockets( + opts: BroadcastOptions, + rooms: Room[], + ): void | Promise { this.apply(opts, (socket) => { socket.join(rooms); }); @@ -312,7 +315,10 @@ export class Adapter extends EventEmitter { * @param opts - the filters to apply * @param rooms - the rooms to leave */ - public delSockets(opts: BroadcastOptions, rooms: Room[]): void { + public delSockets( + opts: BroadcastOptions, + rooms: Room[], + ): void | Promise { this.apply(opts, (socket) => { rooms.forEach((room) => socket.leave(room)); }); @@ -324,7 +330,10 @@ export class Adapter extends EventEmitter { * @param opts - the filters to apply * @param close - whether to close the underlying connection */ - public disconnectSockets(opts: BroadcastOptions, close: boolean): void { + public disconnectSockets( + opts: BroadcastOptions, + close: boolean, + ): void | Promise { this.apply(opts, (socket) => { socket.disconnect(close); }); diff --git a/packages/socket.io/lib/broadcast-operator.ts b/packages/socket.io/lib/broadcast-operator.ts index ca7eccf2f4..ee32bb1ca6 100644 --- a/packages/socket.io/lib/broadcast-operator.ts +++ b/packages/socket.io/lib/broadcast-operator.ts @@ -413,8 +413,8 @@ export class BroadcastOperator * * @param room - a room, or an array of rooms */ - public socketsJoin(room: Room | Room[]): void { - this.adapter.addSockets( + public socketsJoin(room: Room | Room[]): void | Promise { + return this.adapter.addSockets( { rooms: this.rooms, except: this.exceptRooms, @@ -438,8 +438,8 @@ export class BroadcastOperator * * @param room - a room, or an array of rooms */ - public socketsLeave(room: Room | Room[]): void { - this.adapter.delSockets( + public socketsLeave(room: Room | Room[]): void | Promise { + return this.adapter.delSockets( { rooms: this.rooms, except: this.exceptRooms, @@ -463,8 +463,8 @@ export class BroadcastOperator * * @param close - whether to close the underlying connection */ - public disconnectSockets(close: boolean = false): void { - this.adapter.disconnectSockets( + public disconnectSockets(close: boolean = false): void | Promise { + return this.adapter.disconnectSockets( { rooms: this.rooms, except: this.exceptRooms, @@ -554,7 +554,7 @@ export class RemoteSocket * * @param {String|Array} room - room or array of rooms */ - public join(room: Room | Room[]): void { + public join(room: Room | Room[]): void | Promise { return this.operator.socketsJoin(room); } @@ -563,7 +563,7 @@ export class RemoteSocket * * @param {String} room */ - public leave(room: Room): void { + public leave(room: Room): void | Promise { return this.operator.socketsLeave(room); }