Skip to content

Commit 7bc4a2e

Browse files
authored
fix(rtc): consistent connection state handling (#655)
1 parent 0ed1835 commit 7bc4a2e

2 files changed

Lines changed: 21 additions & 16 deletions

File tree

.changeset/empty-bugs-pull.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@livekit/rtc-node": patch
3+
---
4+
5+
fix(rtc): consistent connection state handling

packages/livekit-rtc/src/room.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
107107

108108
private _token?: string;
109109
private _serverUrl?: string;
110+
private _connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;
110111

111112
e2eeManager?: E2EEManager;
112-
connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;
113113

114114
remoteParticipants: Map<string, RemoteParticipant> = new Map();
115115
localParticipant?: LocalParticipant;
@@ -118,6 +118,10 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
118118
super();
119119
}
120120

121+
get connectionState() {
122+
return this._connectionState;
123+
}
124+
121125
get name(): string | undefined {
122126
return this.info?.name;
123127
}
@@ -262,7 +266,6 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
262266
this._token = token;
263267
this._serverUrl = url;
264268
this.info = cb.message.value.room!.info;
265-
this.connectionState = ConnectionState.CONN_CONNECTED;
266269
// Reset the abort controller for this connection session so that
267270
// a previous disconnect doesn't immediately cancel new operations.
268271
this.disconnectController = new AbortController();
@@ -281,6 +284,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
281284
rp.trackPublications.set(publication.sid!, publication);
282285
}
283286
}
287+
this.updateConnectionState(ConnectionState.CONN_CONNECTED);
284288
break;
285289
case 'error':
286290
default:
@@ -321,6 +325,14 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
321325
this.removeAllListeners();
322326
}
323327

328+
private updateConnectionState(newState: ConnectionState) {
329+
if (this._connectionState === newState) {
330+
return;
331+
}
332+
this._connectionState = newState;
333+
this.emit(RoomEvent.ConnectionStateChanged, this._connectionState);
334+
}
335+
324336
// Runs at most once per connection session. The FFI layer and explicit
325337
// disconnect() both race to get here — whichever wins emits the events,
326338
// the other is a no-op. A reconnect via connect() clears hasCleanedUp.
@@ -359,12 +371,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
359371
// to reject and clean up their event listeners.
360372
this.disconnectController.abort();
361373

362-
// Only emit ConnectionStateChanged if the FFI 'connectionStateChanged'
363-
// path didn't already flip us to DISCONNECTED.
364-
if (this.connectionState !== ConnectionState.CONN_DISCONNECTED) {
365-
this.connectionState = ConnectionState.CONN_DISCONNECTED;
366-
this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);
367-
}
374+
this.updateConnectionState(ConnectionState.CONN_DISCONNECTED);
368375
this.emit(RoomEvent.Disconnected, reason);
369376
}
370377

@@ -678,14 +685,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
678685
this.emit(RoomEvent.EncryptionError, new Error('internal server error'));
679686
}
680687
} else if (ev.case == 'connectionStateChanged') {
681-
const newState = ev.value.state!;
682-
// Skip redundant transitions — cleanupOnDisconnect may have already
683-
// flipped us to DISCONNECTED, and we don't want to emit the event twice.
684-
if (this.connectionState === newState) {
685-
return;
686-
}
687-
this.connectionState = newState;
688-
this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);
688+
this.updateConnectionState(ev.value.state!);
689689
/*} else if (ev.case == 'connected') {
690690
this.emit(RoomEvent.Connected);*/
691691
} else if (ev.case == 'disconnected') {

0 commit comments

Comments
 (0)