@@ -7,6 +7,7 @@ import type {
7
7
EventNames ,
8
8
EventsMap ,
9
9
TypedEventBroadcaster ,
10
+ DecorateAcknowledgements ,
10
11
DecorateAcknowledgementsWithTimeoutAndMultipleResponses ,
11
12
AllButLast ,
12
13
Last ,
@@ -20,7 +21,9 @@ export class BroadcastOperator<EmitEvents extends EventsMap, SocketData>
20
21
private readonly adapter : Adapter ,
21
22
private readonly rooms : Set < Room > = new Set < Room > ( ) ,
22
23
private readonly exceptRooms : Set < Room > = new Set < Room > ( ) ,
23
- private readonly flags : BroadcastFlags = { }
24
+ private readonly flags : BroadcastFlags & {
25
+ expectSingleResponse ?: boolean ;
26
+ } = { }
24
27
) { }
25
28
26
29
/**
@@ -232,7 +235,10 @@ export class BroadcastOperator<EmitEvents extends EventsMap, SocketData>
232
235
233
236
const timer = setTimeout ( ( ) => {
234
237
timedOut = true ;
235
- ack . apply ( this , [ new Error ( "operation has timed out" ) , responses ] ) ;
238
+ ack . apply ( this , [
239
+ new Error ( "operation has timed out" ) ,
240
+ this . flags . expectSingleResponse ? null : responses ,
241
+ ] ) ;
236
242
} , this . flags . timeout ) ;
237
243
238
244
let expectedServerCount = - 1 ;
@@ -246,7 +252,10 @@ export class BroadcastOperator<EmitEvents extends EventsMap, SocketData>
246
252
responses . length === expectedClientCount
247
253
) {
248
254
clearTimeout ( timer ) ;
249
- ack . apply ( this , [ null , responses ] ) ;
255
+ ack . apply ( this , [
256
+ null ,
257
+ this . flags . expectSingleResponse ? null : responses ,
258
+ ] ) ;
250
259
}
251
260
} ;
252
261
@@ -476,10 +485,44 @@ export class RemoteSocket<EmitEvents extends EventsMap, SocketData>
476
485
this . data = details . data ;
477
486
this . operator = new BroadcastOperator < EmitEvents , SocketData > (
478
487
adapter ,
479
- new Set ( [ this . id ] )
488
+ new Set ( [ this . id ] ) ,
489
+ new Set ( ) ,
490
+ {
491
+ expectSingleResponse : true , // so that remoteSocket.emit() with acknowledgement behaves like socket.emit()
492
+ }
480
493
) ;
481
494
}
482
495
496
+ /**
497
+ * Adds a timeout in milliseconds for the next operation.
498
+ *
499
+ * @example
500
+ * const sockets = await io.fetchSockets();
501
+ *
502
+ * for (const socket of sockets) {
503
+ * if (someCondition) {
504
+ * socket.timeout(1000).emit("some-event", (err) => {
505
+ * if (err) {
506
+ * // the client did not acknowledge the event in the given delay
507
+ * }
508
+ * });
509
+ * }
510
+ * }
511
+ *
512
+ * // note: if possible, using a room instead of looping over all sockets is preferable
513
+ * io.timeout(1000).to(someConditionRoom).emit("some-event", (err, responses) => {
514
+ * // ...
515
+ * });
516
+ *
517
+ * @param timeout
518
+ */
519
+ public timeout ( timeout : number ) {
520
+ return this . operator . timeout ( timeout ) as BroadcastOperator <
521
+ DecorateAcknowledgements < EmitEvents > ,
522
+ SocketData
523
+ > ;
524
+ }
525
+
483
526
public emit < Ev extends EventNames < EmitEvents > > (
484
527
ev : Ev ,
485
528
...args : EventParams < EmitEvents , Ev >
0 commit comments