livekit-client 1.9.1 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.esm.mjs +105 -42
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +1 -0
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +1 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +3 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +1 -0
- package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -0
- package/dist/ts4.2/src/room/Room.d.ts +3 -0
- package/package.json +1 -1
- package/src/api/SignalClient.ts +15 -11
- package/src/room/RTCEngine.ts +34 -1
- package/src/room/Room.ts +87 -42
@@ -14940,7 +14940,7 @@ var uaParser = {exports: {}};
|
|
14940
14940
|
var uaParserExports = uaParser.exports;
|
14941
14941
|
var UAParser = /*@__PURE__*/getDefaultExportFromCjs(uaParserExports);
|
14942
14942
|
|
14943
|
-
var version$1 = "1.9.
|
14943
|
+
var version$1 = "1.9.2";
|
14944
14944
|
|
14945
14945
|
const version = version$1;
|
14946
14946
|
const protocolVersion = 9;
|
@@ -15509,13 +15509,7 @@ class SignalClient {
|
|
15509
15509
|
this.handleSignalResponse(resp);
|
15510
15510
|
};
|
15511
15511
|
this.ws.onclose = ev => {
|
15512
|
-
|
15513
|
-
livekitLogger.debug("websocket connection closed: ".concat(ev.reason));
|
15514
|
-
this.isConnected = false;
|
15515
|
-
if (this.onClose) {
|
15516
|
-
this.onClose(ev.reason);
|
15517
|
-
}
|
15518
|
-
this.ws = undefined;
|
15512
|
+
this.handleOnClose(ev.reason);
|
15519
15513
|
};
|
15520
15514
|
});
|
15521
15515
|
}
|
@@ -15784,6 +15778,17 @@ class SignalClient {
|
|
15784
15778
|
}
|
15785
15779
|
this.isReconnecting = false;
|
15786
15780
|
}
|
15781
|
+
handleOnClose(reason) {
|
15782
|
+
if (!this.isConnected) return;
|
15783
|
+
this.clearPingInterval();
|
15784
|
+
this.clearPingTimeout();
|
15785
|
+
livekitLogger.debug("websocket connection closed: ".concat(reason));
|
15786
|
+
this.isConnected = false;
|
15787
|
+
if (this.onClose) {
|
15788
|
+
this.onClose(reason);
|
15789
|
+
}
|
15790
|
+
this.ws = undefined;
|
15791
|
+
}
|
15787
15792
|
handleWSError(ev) {
|
15788
15793
|
livekitLogger.error('websocket error', ev);
|
15789
15794
|
}
|
@@ -15799,9 +15804,7 @@ class SignalClient {
|
|
15799
15804
|
}
|
15800
15805
|
this.pingTimeout = CriticalTimers.setTimeout(() => {
|
15801
15806
|
livekitLogger.warn("ping timeout triggered. last pong received at: ".concat(new Date(Date.now() - this.pingTimeoutDuration * 1000).toUTCString()));
|
15802
|
-
|
15803
|
-
this.onClose('ping timeout');
|
15804
|
-
}
|
15807
|
+
this.handleOnClose('ping timeout');
|
15805
15808
|
}, this.pingTimeoutDuration * 1000);
|
15806
15809
|
}
|
15807
15810
|
/**
|
@@ -18571,7 +18574,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
18571
18574
|
} else {
|
18572
18575
|
livekitLogger.info("could not recover connection after ".concat(this.reconnectAttempts, " attempts, ").concat(Date.now() - this.reconnectStart, "ms. giving up"));
|
18573
18576
|
this.emit(EngineEvent.Disconnected);
|
18574
|
-
this.close();
|
18577
|
+
await this.close();
|
18575
18578
|
}
|
18576
18579
|
} finally {
|
18577
18580
|
this.attemptingReconnect = false;
|
@@ -18792,6 +18795,30 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
18792
18795
|
async ensurePublisherConnected(kind) {
|
18793
18796
|
await this.ensureDataTransportConnected(kind, false);
|
18794
18797
|
}
|
18798
|
+
/* @internal */
|
18799
|
+
verifyTransport() {
|
18800
|
+
// primary connection
|
18801
|
+
if (!this.primaryPC) {
|
18802
|
+
return false;
|
18803
|
+
}
|
18804
|
+
if (this.primaryPC.connectionState === 'closed' || this.primaryPC.connectionState === 'failed') {
|
18805
|
+
return false;
|
18806
|
+
}
|
18807
|
+
// also verify publisher connection if it's needed or different
|
18808
|
+
if (this.hasPublished && this.subscriberPrimary) {
|
18809
|
+
if (!this.publisher) {
|
18810
|
+
return false;
|
18811
|
+
}
|
18812
|
+
if (this.publisher.pc.connectionState === 'closed' || this.publisher.pc.connectionState === 'failed') {
|
18813
|
+
return false;
|
18814
|
+
}
|
18815
|
+
}
|
18816
|
+
// ensure signal is connected
|
18817
|
+
if (!this.client.ws || this.client.ws.readyState === WebSocket.CLOSED) {
|
18818
|
+
return false;
|
18819
|
+
}
|
18820
|
+
return true;
|
18821
|
+
}
|
18795
18822
|
/** @internal */
|
18796
18823
|
negotiate() {
|
18797
18824
|
// observe signal state
|
@@ -22242,6 +22269,7 @@ var ConnectionState;
|
|
22242
22269
|
ConnectionState["Connected"] = "connected";
|
22243
22270
|
ConnectionState["Reconnecting"] = "reconnecting";
|
22244
22271
|
})(ConnectionState || (ConnectionState = {}));
|
22272
|
+
const connectionReconcileFrequency = 2 * 1000;
|
22245
22273
|
/** @deprecated RoomState has been renamed to [[ConnectionState]] */
|
22246
22274
|
const RoomState = ConnectionState;
|
22247
22275
|
/**
|
@@ -22421,6 +22449,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22421
22449
|
}
|
22422
22450
|
this.setAndEmitConnectionState(ConnectionState.Connected);
|
22423
22451
|
this.emit(RoomEvent.Connected);
|
22452
|
+
this.registerConnectionReconcile();
|
22424
22453
|
};
|
22425
22454
|
/**
|
22426
22455
|
* disconnects the room, emits [[RoomEvent.Disconnected]]
|
@@ -22464,6 +22493,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22464
22493
|
await this.disconnect();
|
22465
22494
|
};
|
22466
22495
|
this.handleRestarting = () => {
|
22496
|
+
this.clearConnectionReconcile();
|
22467
22497
|
// also unwind existing participants & existing subscriptions
|
22468
22498
|
for (const p of this.participants.values()) {
|
22469
22499
|
this.handleParticipantDisconnected(p.sid, p);
|
@@ -22520,6 +22550,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22520
22550
|
}
|
22521
22551
|
this.setAndEmitConnectionState(ConnectionState.Connected);
|
22522
22552
|
this.emit(RoomEvent.Reconnected);
|
22553
|
+
this.registerConnectionReconcile();
|
22523
22554
|
// emit participant connected events after connection has been re-established
|
22524
22555
|
this.participants.forEach(participant => {
|
22525
22556
|
this.emit(RoomEvent.ParticipantConnected, participant);
|
@@ -22761,7 +22792,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22761
22792
|
return (_b = (_a = this.roomInfo) === null || _a === void 0 ? void 0 : _a.numPublishers) !== null && _b !== void 0 ? _b : 0;
|
22762
22793
|
}
|
22763
22794
|
maybeCreateEngine() {
|
22764
|
-
if (this.engine) {
|
22795
|
+
if (this.engine && !this.engine.isClosed) {
|
22765
22796
|
return;
|
22766
22797
|
}
|
22767
22798
|
this.engine = new RTCEngine(this.options);
|
@@ -22776,6 +22807,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22776
22807
|
}).on(EngineEvent.Disconnected, reason => {
|
22777
22808
|
this.handleDisconnect(this.options.stopLocalTrackOnUnpublish, reason);
|
22778
22809
|
}).on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate).on(EngineEvent.DataPacketReceived, this.handleDataPacket).on(EngineEvent.Resuming, () => {
|
22810
|
+
this.clearConnectionReconcile();
|
22779
22811
|
if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
|
22780
22812
|
this.emit(RoomEvent.Reconnecting);
|
22781
22813
|
}
|
@@ -22783,6 +22815,7 @@ class Room extends eventsExports.EventEmitter {
|
|
22783
22815
|
}).on(EngineEvent.Resumed, () => {
|
22784
22816
|
this.setAndEmitConnectionState(ConnectionState.Connected);
|
22785
22817
|
this.emit(RoomEvent.Reconnected);
|
22818
|
+
this.registerConnectionReconcile();
|
22786
22819
|
this.updateSubscriptions();
|
22787
22820
|
// once reconnected, figure out if any participants connected during reconnect and emit events for it
|
22788
22821
|
const diffParticipants = Array.from(this.participants.values()).filter(p => !this.cachedParticipantSids.includes(p.sid));
|
@@ -23093,41 +23126,45 @@ class Room extends eventsExports.EventEmitter {
|
|
23093
23126
|
let shouldStopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
23094
23127
|
let reason = arguments.length > 1 ? arguments[1] : undefined;
|
23095
23128
|
var _a;
|
23129
|
+
this.clearConnectionReconcile();
|
23096
23130
|
if (this.state === ConnectionState.Disconnected) {
|
23097
23131
|
return;
|
23098
23132
|
}
|
23099
|
-
|
23100
|
-
|
23101
|
-
p.
|
23133
|
+
try {
|
23134
|
+
this.participants.forEach(p => {
|
23135
|
+
p.tracks.forEach(pub => {
|
23136
|
+
p.unpublishTrack(pub.trackSid);
|
23137
|
+
});
|
23102
23138
|
});
|
23103
|
-
|
23104
|
-
|
23105
|
-
|
23106
|
-
|
23107
|
-
|
23108
|
-
|
23109
|
-
|
23110
|
-
|
23111
|
-
|
23139
|
+
this.localParticipant.tracks.forEach(pub => {
|
23140
|
+
var _a, _b;
|
23141
|
+
if (pub.track) {
|
23142
|
+
this.localParticipant.unpublishTrack(pub.track, shouldStopTracks);
|
23143
|
+
}
|
23144
|
+
if (shouldStopTracks) {
|
23145
|
+
(_a = pub.track) === null || _a === void 0 ? void 0 : _a.detach();
|
23146
|
+
(_b = pub.track) === null || _b === void 0 ? void 0 : _b.stop();
|
23147
|
+
}
|
23148
|
+
});
|
23149
|
+
this.localParticipant.off(ParticipantEvent.ParticipantMetadataChanged, this.onLocalParticipantMetadataChanged).off(ParticipantEvent.ParticipantNameChanged, this.onLocalParticipantNameChanged).off(ParticipantEvent.TrackMuted, this.onLocalTrackMuted).off(ParticipantEvent.TrackUnmuted, this.onLocalTrackUnmuted).off(ParticipantEvent.LocalTrackPublished, this.onLocalTrackPublished).off(ParticipantEvent.LocalTrackUnpublished, this.onLocalTrackUnpublished).off(ParticipantEvent.ConnectionQualityChanged, this.onLocalConnectionQualityChanged).off(ParticipantEvent.MediaDevicesError, this.onMediaDevicesError).off(ParticipantEvent.ParticipantPermissionsChanged, this.onLocalParticipantPermissionsChanged);
|
23150
|
+
this.localParticipant.tracks.clear();
|
23151
|
+
this.localParticipant.videoTracks.clear();
|
23152
|
+
this.localParticipant.audioTracks.clear();
|
23153
|
+
this.participants.clear();
|
23154
|
+
this.activeSpeakers = [];
|
23155
|
+
if (this.audioContext && typeof this.options.expWebAudioMix === 'boolean') {
|
23156
|
+
this.audioContext.close();
|
23157
|
+
this.audioContext = undefined;
|
23158
|
+
}
|
23159
|
+
if (isWeb()) {
|
23160
|
+
window.removeEventListener('beforeunload', this.onPageLeave);
|
23161
|
+
window.removeEventListener('pagehide', this.onPageLeave);
|
23162
|
+
(_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
|
23112
23163
|
}
|
23113
|
-
}
|
23114
|
-
|
23115
|
-
|
23116
|
-
this.localParticipant.videoTracks.clear();
|
23117
|
-
this.localParticipant.audioTracks.clear();
|
23118
|
-
this.participants.clear();
|
23119
|
-
this.activeSpeakers = [];
|
23120
|
-
if (this.audioContext && typeof this.options.expWebAudioMix === 'boolean') {
|
23121
|
-
this.audioContext.close();
|
23122
|
-
this.audioContext = undefined;
|
23123
|
-
}
|
23124
|
-
if (isWeb()) {
|
23125
|
-
window.removeEventListener('beforeunload', this.onPageLeave);
|
23126
|
-
window.removeEventListener('pagehide', this.onPageLeave);
|
23127
|
-
(_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
|
23164
|
+
} finally {
|
23165
|
+
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
23166
|
+
this.emit(RoomEvent.Disconnected, reason);
|
23128
23167
|
}
|
23129
|
-
this.setAndEmitConnectionState(ConnectionState.Disconnected);
|
23130
|
-
this.emit(RoomEvent.Disconnected, reason);
|
23131
23168
|
}
|
23132
23169
|
handleParticipantDisconnected(sid, participant) {
|
23133
23170
|
// remove and send event
|
@@ -23280,6 +23317,32 @@ class Room extends eventsExports.EventEmitter {
|
|
23280
23317
|
}
|
23281
23318
|
}
|
23282
23319
|
}
|
23320
|
+
registerConnectionReconcile() {
|
23321
|
+
this.clearConnectionReconcile();
|
23322
|
+
let consecutiveFailures = 0;
|
23323
|
+
this.connectionReconcileInterval = CriticalTimers.setInterval(() => {
|
23324
|
+
if (
|
23325
|
+
// ensure we didn't tear it down
|
23326
|
+
!this.engine ||
|
23327
|
+
// engine detected close, but Room missed it
|
23328
|
+
this.engine.isClosed ||
|
23329
|
+
// transports failed without notifying engine
|
23330
|
+
!this.engine.verifyTransport()) {
|
23331
|
+
consecutiveFailures++;
|
23332
|
+
livekitLogger.warn('detected connection state mismatch', {
|
23333
|
+
numFailures: consecutiveFailures
|
23334
|
+
});
|
23335
|
+
if (consecutiveFailures >= 3) this.handleDisconnect(this.options.stopLocalTrackOnUnpublish, DisconnectReason.UNKNOWN_REASON);
|
23336
|
+
} else {
|
23337
|
+
consecutiveFailures = 0;
|
23338
|
+
}
|
23339
|
+
}, connectionReconcileFrequency);
|
23340
|
+
}
|
23341
|
+
clearConnectionReconcile() {
|
23342
|
+
if (this.connectionReconcileInterval) {
|
23343
|
+
CriticalTimers.clearInterval(this.connectionReconcileInterval);
|
23344
|
+
}
|
23345
|
+
}
|
23283
23346
|
setAndEmitConnectionState(state) {
|
23284
23347
|
if (state === this.state) {
|
23285
23348
|
// unchanged
|