livekit-client 1.9.1 → 1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|