Skip to content

Commit f83124d

Browse files
committed
Buffer room events during reconnect (#1007)
1 parent 1200535 commit f83124d

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

.changeset/chilled-actors-fix.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"livekit-client": patch
3+
---
4+
5+
Buffer room events during reconnect

src/room/Room.ts

+18-17
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
141141

142142
private e2eeManager: E2EEManager | undefined;
143143

144-
private cachedParticipantSids: Array<string>;
145-
146144
private connectionReconcileInterval?: ReturnType<typeof setInterval>;
147145

148146
private regionUrlProvider?: RegionUrlProvider;
@@ -153,6 +151,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
153151

154152
private log = log;
155153

154+
private bufferedEvents: Array<any> = [];
155+
156156
/**
157157
* Creates a new Room, the primary construct for a LiveKit session.
158158
* @param options
@@ -161,7 +161,6 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
161161
super();
162162
this.setMaxListeners(100);
163163
this.participants = new Map();
164-
this.cachedParticipantSids = [];
165164
this.identityToSid = new Map();
166165
this.options = { ...roomOptionDefaults, ...options };
167166

@@ -312,22 +311,16 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
312311
if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
313312
this.emit(RoomEvent.Reconnecting);
314313
}
315-
this.cachedParticipantSids = Array.from(this.participants.keys());
316314
})
317315
.on(EngineEvent.Resumed, () => {
318316
this.setAndEmitConnectionState(ConnectionState.Connected);
319317
this.emit(RoomEvent.Reconnected);
320318
this.registerConnectionReconcile();
321319
this.updateSubscriptions();
322-
323-
// once reconnected, figure out if any participants connected during reconnect and emit events for it
324-
const diffParticipants = Array.from(this.participants.values()).filter(
325-
(p) => !this.cachedParticipantSids.includes(p.sid),
326-
);
327-
diffParticipants.forEach((p) => this.emit(RoomEvent.ParticipantConnected, p));
328-
this.cachedParticipantSids = [];
320+
this.emitBufferedEvents();
329321
})
330322
.on(EngineEvent.SignalResumed, () => {
323+
this.bufferedEvents = [];
331324
if (this.state === ConnectionState.Reconnecting) {
332325
this.sendSyncState();
333326
}
@@ -1072,6 +1065,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
10721065
// clear out existing remote participants, since they may have attached
10731066
// the old engine
10741067
this.participants.clear();
1068+
this.bufferedEvents = [];
10751069
this.maybeCreateEngine();
10761070
}
10771071

@@ -1161,8 +1155,8 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
11611155
...this.logContext,
11621156
region: joinResponse.serverRegion,
11631157
});
1158+
this.bufferedEvents = [];
11641159

1165-
this.cachedParticipantSids = [];
11661160
this.applyJoinResponse(joinResponse);
11671161

11681162
try {
@@ -1188,15 +1182,12 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
11881182
this.setAndEmitConnectionState(ConnectionState.Connected);
11891183
this.emit(RoomEvent.Reconnected);
11901184
this.registerConnectionReconcile();
1191-
1192-
// emit participant connected events after connection has been re-established
1193-
this.participants.forEach((participant) => {
1194-
this.emit(RoomEvent.ParticipantConnected, participant);
1195-
});
1185+
this.emitBufferedEvents();
11961186
};
11971187

11981188
private handleDisconnect(shouldStopTracks = true, reason?: DisconnectReason) {
11991189
this.clearConnectionReconcile();
1190+
this.bufferedEvents = [];
12001191
if (this.state === ConnectionState.Disconnected) {
12011192
return;
12021193
}
@@ -1707,12 +1698,22 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
17071698
return true;
17081699
}
17091700

1701+
private emitBufferedEvents() {
1702+
this.bufferedEvents.forEach(([ev, args]) => {
1703+
this.emit(ev, ...args);
1704+
});
1705+
this.bufferedEvents = [];
1706+
}
1707+
17101708
private emitWhenConnected<E extends keyof RoomEventCallbacks>(
17111709
event: E,
17121710
...args: Parameters<RoomEventCallbacks[E]>
17131711
): boolean {
17141712
if (this.state === ConnectionState.Connected) {
17151713
return this.emit(event, ...args);
1714+
} else if (this.state === ConnectionState.Reconnecting) {
1715+
// in case the room is reconnecting, buffer the events by firing them later after emitting RoomEvent.Reconnected
1716+
this.bufferedEvents.push([event, args]);
17161717
}
17171718
return false;
17181719
}

0 commit comments

Comments
 (0)