From a7f1c90a322241ffaca96ddc42f204d79bc514b5 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Tue, 29 Mar 2022 08:28:54 +0200 Subject: [PATCH] feat: broadcast and expect multiple acks Tests will be added in the parent repository. Related: - https://github.com/socketio/socket.io/issues/1811 - https://github.com/socketio/socket.io/issues/4163 --- lib/index.ts | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/index.ts b/lib/index.ts index 9220d6e..f293c06 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -9,6 +9,7 @@ export interface BroadcastFlags { local?: boolean; broadcast?: boolean; binary?: boolean; + timeout?: number; } export interface BroadcastOptions { @@ -42,6 +43,15 @@ export class Adapter extends EventEmitter { */ public close(): Promise | void {} + /** + * Returns the number of Socket.IO servers in the cluster + * + * @public + */ + public serverCount(): Promise { + return Promise.resolve(1); + } + /** * Adds a socket to a list of room. * @@ -140,6 +150,54 @@ export class Adapter extends EventEmitter { }); } + /** + * Broadcasts a packet and expects multiple acknowledgements. + * + * Options: + * - `flags` {Object} flags for this packet + * - `except` {Array} sids that should be excluded + * - `rooms` {Array} list of rooms to broadcast to + * + * @param {Object} packet the packet object + * @param {Object} opts the options + * @param clientCountCallback - the number of clients that received the packet + * @param ack - the callback that will be called for each client response + * + * @public + */ + public broadcastWithAck( + packet: any, + opts: BroadcastOptions, + clientCountCallback: (clientCount: number) => void, + ack: (...args: any[]) => void + ) { + const flags = opts.flags || {}; + const packetOpts = { + preEncoded: true, + volatile: flags.volatile, + compress: flags.compress + }; + + packet.nsp = this.nsp.name; + // we can use the same id for each packet, since the _ids counter is common (no duplicate) + packet.id = this.nsp._ids++; + + const encodedPackets = this.encoder.encode(packet); + + let clientCount = 0; + + this.apply(opts, socket => { + // track the total number of acknowledgements that are expected + clientCount++; + // call the ack callback for each client response + socket.acks.set(packet.id, ack); + + socket.client.writeToEngine(encodedPackets, packetOpts); + }); + + clientCountCallback(clientCount); + } + /** * Gets a list of sockets by sid. *