livekit-client 1.6.4 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.esm.mjs +264 -33
- 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 +13 -2
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +10 -0
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +2395 -384
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +13 -2
- package/dist/ts4.2/src/proto/livekit_models.d.ts +10 -0
- package/dist/ts4.2/src/proto/livekit_rtc.d.ts +2567 -440
- package/package.json +1 -1
- package/src/api/SignalClient.ts +41 -2
- package/src/proto/livekit_models.ts +51 -0
- package/src/proto/livekit_rtc.ts +210 -3
- package/src/room/RTCEngine.ts +35 -14
- package/src/room/Room.ts +8 -4
- package/src/room/participant/LocalParticipant.ts +7 -3
- package/src/room/track/LocalAudioTrack.ts +5 -1
package/package.json
CHANGED
package/src/api/SignalClient.ts
CHANGED
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
ClientInfo,
|
6
6
|
DisconnectReason,
|
7
7
|
ParticipantInfo,
|
8
|
+
ReconnectReason,
|
8
9
|
Room,
|
9
10
|
SpeakerInfo,
|
10
11
|
VideoLayer,
|
@@ -40,6 +41,9 @@ interface ConnectOpts {
|
|
40
41
|
/** internal */
|
41
42
|
reconnect?: boolean;
|
42
43
|
|
44
|
+
/** internal */
|
45
|
+
reconnectReason?: number;
|
46
|
+
|
43
47
|
/** internal */
|
44
48
|
sid?: string;
|
45
49
|
|
@@ -89,6 +93,9 @@ export class SignalClient {
|
|
89
93
|
|
90
94
|
useJSON: boolean;
|
91
95
|
|
96
|
+
/** signal rtt in milliseconds */
|
97
|
+
rtt: number = 0;
|
98
|
+
|
92
99
|
/** simulate signaling latency by delaying messages */
|
93
100
|
signalLatency?: number;
|
94
101
|
|
@@ -166,7 +173,12 @@ export class SignalClient {
|
|
166
173
|
return res as JoinResponse;
|
167
174
|
}
|
168
175
|
|
169
|
-
async reconnect(
|
176
|
+
async reconnect(
|
177
|
+
url: string,
|
178
|
+
token: string,
|
179
|
+
sid?: string,
|
180
|
+
reason?: ReconnectReason,
|
181
|
+
): Promise<ReconnectResponse | void> {
|
170
182
|
if (!this.options) {
|
171
183
|
log.warn('attempted to reconnect without signal options being set, ignoring');
|
172
184
|
return;
|
@@ -175,7 +187,12 @@ export class SignalClient {
|
|
175
187
|
// clear ping interval and restart it once reconnected
|
176
188
|
this.clearPingInterval();
|
177
189
|
|
178
|
-
const res = await this.connect(url, token, {
|
190
|
+
const res = await this.connect(url, token, {
|
191
|
+
...this.options,
|
192
|
+
reconnect: true,
|
193
|
+
sid,
|
194
|
+
reconnectReason: reason,
|
195
|
+
});
|
179
196
|
return res;
|
180
197
|
}
|
181
198
|
|
@@ -440,10 +457,18 @@ export class SignalClient {
|
|
440
457
|
}
|
441
458
|
|
442
459
|
sendPing() {
|
460
|
+
/** send both of ping and pingReq for compatibility to old and new server */
|
443
461
|
this.sendRequest({
|
444
462
|
$case: 'ping',
|
445
463
|
ping: Date.now(),
|
446
464
|
});
|
465
|
+
this.sendRequest({
|
466
|
+
$case: 'pingReq',
|
467
|
+
pingReq: {
|
468
|
+
timestamp: Date.now(),
|
469
|
+
rtt: this.rtt,
|
470
|
+
},
|
471
|
+
});
|
447
472
|
}
|
448
473
|
|
449
474
|
async sendLeave() {
|
@@ -563,6 +588,9 @@ export class SignalClient {
|
|
563
588
|
}
|
564
589
|
} else if (msg.$case === 'pong') {
|
565
590
|
this.resetPingTimeout();
|
591
|
+
} else if (msg.$case === 'pongResp') {
|
592
|
+
this.rtt = Date.now() - msg.pongResp.lastPingTimestamp;
|
593
|
+
this.resetPingTimeout();
|
566
594
|
} else {
|
567
595
|
log.debug('unsupported message', msg);
|
568
596
|
}
|
@@ -582,6 +610,10 @@ export class SignalClient {
|
|
582
610
|
log.error('websocket error', ev);
|
583
611
|
}
|
584
612
|
|
613
|
+
/**
|
614
|
+
* Resets the ping timeout and starts a new timeout.
|
615
|
+
* Call this after receiving a pong message
|
616
|
+
*/
|
585
617
|
private resetPingTimeout() {
|
586
618
|
this.clearPingTimeout();
|
587
619
|
if (!this.pingTimeoutDuration) {
|
@@ -600,6 +632,9 @@ export class SignalClient {
|
|
600
632
|
}, this.pingTimeoutDuration * 1000);
|
601
633
|
}
|
602
634
|
|
635
|
+
/**
|
636
|
+
* Clears ping timeout (does not start a new timeout)
|
637
|
+
*/
|
603
638
|
private clearPingTimeout() {
|
604
639
|
if (this.pingTimeout) {
|
605
640
|
CriticalTimers.clearTimeout(this.pingTimeout);
|
@@ -698,6 +733,10 @@ function createConnectionParams(token: string, info: ClientInfo, opts: ConnectOp
|
|
698
733
|
params.set('adaptive_stream', '1');
|
699
734
|
}
|
700
735
|
|
736
|
+
if (opts.reconnectReason) {
|
737
|
+
params.set('reconnect_reason', opts.reconnectReason.toString());
|
738
|
+
}
|
739
|
+
|
701
740
|
// @ts-ignore
|
702
741
|
if (navigator.connection?.type) {
|
703
742
|
// @ts-ignore
|
@@ -287,6 +287,57 @@ export function disconnectReasonToJSON(object: DisconnectReason): string {
|
|
287
287
|
}
|
288
288
|
}
|
289
289
|
|
290
|
+
export enum ReconnectReason {
|
291
|
+
REASON_UNKOWN = 0,
|
292
|
+
REASON_SIGNAL_DISCONNECTED = 1,
|
293
|
+
REASON_PUBLISHER_FAILED = 2,
|
294
|
+
REASON_SUBSCRIBER_FAILED = 3,
|
295
|
+
REASON_SWITCH_CANDIDATE = 4,
|
296
|
+
UNRECOGNIZED = -1,
|
297
|
+
}
|
298
|
+
|
299
|
+
export function reconnectReasonFromJSON(object: any): ReconnectReason {
|
300
|
+
switch (object) {
|
301
|
+
case 0:
|
302
|
+
case "REASON_UNKOWN":
|
303
|
+
return ReconnectReason.REASON_UNKOWN;
|
304
|
+
case 1:
|
305
|
+
case "REASON_SIGNAL_DISCONNECTED":
|
306
|
+
return ReconnectReason.REASON_SIGNAL_DISCONNECTED;
|
307
|
+
case 2:
|
308
|
+
case "REASON_PUBLISHER_FAILED":
|
309
|
+
return ReconnectReason.REASON_PUBLISHER_FAILED;
|
310
|
+
case 3:
|
311
|
+
case "REASON_SUBSCRIBER_FAILED":
|
312
|
+
return ReconnectReason.REASON_SUBSCRIBER_FAILED;
|
313
|
+
case 4:
|
314
|
+
case "REASON_SWITCH_CANDIDATE":
|
315
|
+
return ReconnectReason.REASON_SWITCH_CANDIDATE;
|
316
|
+
case -1:
|
317
|
+
case "UNRECOGNIZED":
|
318
|
+
default:
|
319
|
+
return ReconnectReason.UNRECOGNIZED;
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
export function reconnectReasonToJSON(object: ReconnectReason): string {
|
324
|
+
switch (object) {
|
325
|
+
case ReconnectReason.REASON_UNKOWN:
|
326
|
+
return "REASON_UNKOWN";
|
327
|
+
case ReconnectReason.REASON_SIGNAL_DISCONNECTED:
|
328
|
+
return "REASON_SIGNAL_DISCONNECTED";
|
329
|
+
case ReconnectReason.REASON_PUBLISHER_FAILED:
|
330
|
+
return "REASON_PUBLISHER_FAILED";
|
331
|
+
case ReconnectReason.REASON_SUBSCRIBER_FAILED:
|
332
|
+
return "REASON_SUBSCRIBER_FAILED";
|
333
|
+
case ReconnectReason.REASON_SWITCH_CANDIDATE:
|
334
|
+
return "REASON_SWITCH_CANDIDATE";
|
335
|
+
case ReconnectReason.UNRECOGNIZED:
|
336
|
+
default:
|
337
|
+
return "UNRECOGNIZED";
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
290
341
|
export interface Room {
|
291
342
|
sid: string;
|
292
343
|
name: string;
|
package/src/proto/livekit_rtc.ts
CHANGED
@@ -152,7 +152,8 @@ export interface SignalRequest {
|
|
152
152
|
| { $case: "syncState"; syncState: SyncState }
|
153
153
|
| { $case: "simulate"; simulate: SimulateScenario }
|
154
154
|
| { $case: "ping"; ping: number }
|
155
|
-
| { $case: "updateMetadata"; updateMetadata: UpdateParticipantMetadata }
|
155
|
+
| { $case: "updateMetadata"; updateMetadata: UpdateParticipantMetadata }
|
156
|
+
| { $case: "pingReq"; pingReq: Ping };
|
156
157
|
}
|
157
158
|
|
158
159
|
export interface SignalResponse {
|
@@ -174,7 +175,8 @@ export interface SignalResponse {
|
|
174
175
|
| { $case: "refreshToken"; refreshToken: string }
|
175
176
|
| { $case: "trackUnpublished"; trackUnpublished: TrackUnpublishedResponse }
|
176
177
|
| { $case: "pong"; pong: number }
|
177
|
-
| { $case: "reconnect"; reconnect: ReconnectResponse }
|
178
|
+
| { $case: "reconnect"; reconnect: ReconnectResponse }
|
179
|
+
| { $case: "pongResp"; pongResp: Pong };
|
178
180
|
}
|
179
181
|
|
180
182
|
export interface SimulcastCodec {
|
@@ -241,6 +243,9 @@ export interface JoinResponse {
|
|
241
243
|
export interface ReconnectResponse {
|
242
244
|
iceServers: ICEServer[];
|
243
245
|
clientConfiguration?: ClientConfiguration;
|
246
|
+
room?: Room;
|
247
|
+
participant?: ParticipantInfo;
|
248
|
+
otherParticipants: ParticipantInfo[];
|
244
249
|
}
|
245
250
|
|
246
251
|
export interface TrackPublishedResponse {
|
@@ -404,6 +409,18 @@ export interface SimulateScenario {
|
|
404
409
|
| { $case: "switchCandidateProtocol"; switchCandidateProtocol: CandidateProtocol };
|
405
410
|
}
|
406
411
|
|
412
|
+
export interface Ping {
|
413
|
+
timestamp: number;
|
414
|
+
/** rtt in milliseconds calculated by client */
|
415
|
+
rtt: number;
|
416
|
+
}
|
417
|
+
|
418
|
+
export interface Pong {
|
419
|
+
/** timestamp field of last received ping request */
|
420
|
+
lastPingTimestamp: number;
|
421
|
+
timestamp: number;
|
422
|
+
}
|
423
|
+
|
407
424
|
function createBaseSignalRequest(): SignalRequest {
|
408
425
|
return { message: undefined };
|
409
426
|
}
|
@@ -452,6 +469,9 @@ export const SignalRequest = {
|
|
452
469
|
if (message.message?.$case === "updateMetadata") {
|
453
470
|
UpdateParticipantMetadata.encode(message.message.updateMetadata, writer.uint32(122).fork()).ldelim();
|
454
471
|
}
|
472
|
+
if (message.message?.$case === "pingReq") {
|
473
|
+
Ping.encode(message.message.pingReq, writer.uint32(130).fork()).ldelim();
|
474
|
+
}
|
455
475
|
return writer;
|
456
476
|
},
|
457
477
|
|
@@ -513,6 +533,9 @@ export const SignalRequest = {
|
|
513
533
|
updateMetadata: UpdateParticipantMetadata.decode(reader, reader.uint32()),
|
514
534
|
};
|
515
535
|
break;
|
536
|
+
case 16:
|
537
|
+
message.message = { $case: "pingReq", pingReq: Ping.decode(reader, reader.uint32()) };
|
538
|
+
break;
|
516
539
|
default:
|
517
540
|
reader.skipType(tag & 7);
|
518
541
|
break;
|
@@ -554,6 +577,8 @@ export const SignalRequest = {
|
|
554
577
|
? { $case: "ping", ping: Number(object.ping) }
|
555
578
|
: isSet(object.updateMetadata)
|
556
579
|
? { $case: "updateMetadata", updateMetadata: UpdateParticipantMetadata.fromJSON(object.updateMetadata) }
|
580
|
+
: isSet(object.pingReq)
|
581
|
+
? { $case: "pingReq", pingReq: Ping.fromJSON(object.pingReq) }
|
557
582
|
: undefined,
|
558
583
|
};
|
559
584
|
},
|
@@ -593,6 +618,8 @@ export const SignalRequest = {
|
|
593
618
|
message.message?.$case === "updateMetadata" && (obj.updateMetadata = message.message?.updateMetadata
|
594
619
|
? UpdateParticipantMetadata.toJSON(message.message?.updateMetadata)
|
595
620
|
: undefined);
|
621
|
+
message.message?.$case === "pingReq" &&
|
622
|
+
(obj.pingReq = message.message?.pingReq ? Ping.toJSON(message.message?.pingReq) : undefined);
|
596
623
|
return obj;
|
597
624
|
},
|
598
625
|
|
@@ -689,6 +716,11 @@ export const SignalRequest = {
|
|
689
716
|
updateMetadata: UpdateParticipantMetadata.fromPartial(object.message.updateMetadata),
|
690
717
|
};
|
691
718
|
}
|
719
|
+
if (
|
720
|
+
object.message?.$case === "pingReq" && object.message?.pingReq !== undefined && object.message?.pingReq !== null
|
721
|
+
) {
|
722
|
+
message.message = { $case: "pingReq", pingReq: Ping.fromPartial(object.message.pingReq) };
|
723
|
+
}
|
692
724
|
return message;
|
693
725
|
},
|
694
726
|
};
|
@@ -754,6 +786,9 @@ export const SignalResponse = {
|
|
754
786
|
if (message.message?.$case === "reconnect") {
|
755
787
|
ReconnectResponse.encode(message.message.reconnect, writer.uint32(154).fork()).ldelim();
|
756
788
|
}
|
789
|
+
if (message.message?.$case === "pongResp") {
|
790
|
+
Pong.encode(message.message.pongResp, writer.uint32(162).fork()).ldelim();
|
791
|
+
}
|
757
792
|
return writer;
|
758
793
|
},
|
759
794
|
|
@@ -839,6 +874,9 @@ export const SignalResponse = {
|
|
839
874
|
case 19:
|
840
875
|
message.message = { $case: "reconnect", reconnect: ReconnectResponse.decode(reader, reader.uint32()) };
|
841
876
|
break;
|
877
|
+
case 20:
|
878
|
+
message.message = { $case: "pongResp", pongResp: Pong.decode(reader, reader.uint32()) };
|
879
|
+
break;
|
842
880
|
default:
|
843
881
|
reader.skipType(tag & 7);
|
844
882
|
break;
|
@@ -891,6 +929,8 @@ export const SignalResponse = {
|
|
891
929
|
? { $case: "pong", pong: Number(object.pong) }
|
892
930
|
: isSet(object.reconnect)
|
893
931
|
? { $case: "reconnect", reconnect: ReconnectResponse.fromJSON(object.reconnect) }
|
932
|
+
: isSet(object.pongResp)
|
933
|
+
? { $case: "pongResp", pongResp: Pong.fromJSON(object.pongResp) }
|
894
934
|
: undefined,
|
895
935
|
};
|
896
936
|
},
|
@@ -940,6 +980,8 @@ export const SignalResponse = {
|
|
940
980
|
message.message?.$case === "pong" && (obj.pong = Math.round(message.message?.pong));
|
941
981
|
message.message?.$case === "reconnect" &&
|
942
982
|
(obj.reconnect = message.message?.reconnect ? ReconnectResponse.toJSON(message.message?.reconnect) : undefined);
|
983
|
+
message.message?.$case === "pongResp" &&
|
984
|
+
(obj.pongResp = message.message?.pongResp ? Pong.toJSON(message.message?.pongResp) : undefined);
|
943
985
|
return obj;
|
944
986
|
},
|
945
987
|
|
@@ -1064,6 +1106,13 @@ export const SignalResponse = {
|
|
1064
1106
|
) {
|
1065
1107
|
message.message = { $case: "reconnect", reconnect: ReconnectResponse.fromPartial(object.message.reconnect) };
|
1066
1108
|
}
|
1109
|
+
if (
|
1110
|
+
object.message?.$case === "pongResp" &&
|
1111
|
+
object.message?.pongResp !== undefined &&
|
1112
|
+
object.message?.pongResp !== null
|
1113
|
+
) {
|
1114
|
+
message.message = { $case: "pongResp", pongResp: Pong.fromPartial(object.message.pongResp) };
|
1115
|
+
}
|
1067
1116
|
return message;
|
1068
1117
|
},
|
1069
1118
|
};
|
@@ -1626,7 +1675,13 @@ export const JoinResponse = {
|
|
1626
1675
|
};
|
1627
1676
|
|
1628
1677
|
function createBaseReconnectResponse(): ReconnectResponse {
|
1629
|
-
return {
|
1678
|
+
return {
|
1679
|
+
iceServers: [],
|
1680
|
+
clientConfiguration: undefined,
|
1681
|
+
room: undefined,
|
1682
|
+
participant: undefined,
|
1683
|
+
otherParticipants: [],
|
1684
|
+
};
|
1630
1685
|
}
|
1631
1686
|
|
1632
1687
|
export const ReconnectResponse = {
|
@@ -1637,6 +1692,15 @@ export const ReconnectResponse = {
|
|
1637
1692
|
if (message.clientConfiguration !== undefined) {
|
1638
1693
|
ClientConfiguration.encode(message.clientConfiguration, writer.uint32(18).fork()).ldelim();
|
1639
1694
|
}
|
1695
|
+
if (message.room !== undefined) {
|
1696
|
+
Room.encode(message.room, writer.uint32(26).fork()).ldelim();
|
1697
|
+
}
|
1698
|
+
if (message.participant !== undefined) {
|
1699
|
+
ParticipantInfo.encode(message.participant, writer.uint32(34).fork()).ldelim();
|
1700
|
+
}
|
1701
|
+
for (const v of message.otherParticipants) {
|
1702
|
+
ParticipantInfo.encode(v!, writer.uint32(42).fork()).ldelim();
|
1703
|
+
}
|
1640
1704
|
return writer;
|
1641
1705
|
},
|
1642
1706
|
|
@@ -1653,6 +1717,15 @@ export const ReconnectResponse = {
|
|
1653
1717
|
case 2:
|
1654
1718
|
message.clientConfiguration = ClientConfiguration.decode(reader, reader.uint32());
|
1655
1719
|
break;
|
1720
|
+
case 3:
|
1721
|
+
message.room = Room.decode(reader, reader.uint32());
|
1722
|
+
break;
|
1723
|
+
case 4:
|
1724
|
+
message.participant = ParticipantInfo.decode(reader, reader.uint32());
|
1725
|
+
break;
|
1726
|
+
case 5:
|
1727
|
+
message.otherParticipants.push(ParticipantInfo.decode(reader, reader.uint32()));
|
1728
|
+
break;
|
1656
1729
|
default:
|
1657
1730
|
reader.skipType(tag & 7);
|
1658
1731
|
break;
|
@@ -1667,6 +1740,11 @@ export const ReconnectResponse = {
|
|
1667
1740
|
clientConfiguration: isSet(object.clientConfiguration)
|
1668
1741
|
? ClientConfiguration.fromJSON(object.clientConfiguration)
|
1669
1742
|
: undefined,
|
1743
|
+
room: isSet(object.room) ? Room.fromJSON(object.room) : undefined,
|
1744
|
+
participant: isSet(object.participant) ? ParticipantInfo.fromJSON(object.participant) : undefined,
|
1745
|
+
otherParticipants: Array.isArray(object?.otherParticipants)
|
1746
|
+
? object.otherParticipants.map((e: any) => ParticipantInfo.fromJSON(e))
|
1747
|
+
: [],
|
1670
1748
|
};
|
1671
1749
|
},
|
1672
1750
|
|
@@ -1680,6 +1758,14 @@ export const ReconnectResponse = {
|
|
1680
1758
|
message.clientConfiguration !== undefined && (obj.clientConfiguration = message.clientConfiguration
|
1681
1759
|
? ClientConfiguration.toJSON(message.clientConfiguration)
|
1682
1760
|
: undefined);
|
1761
|
+
message.room !== undefined && (obj.room = message.room ? Room.toJSON(message.room) : undefined);
|
1762
|
+
message.participant !== undefined &&
|
1763
|
+
(obj.participant = message.participant ? ParticipantInfo.toJSON(message.participant) : undefined);
|
1764
|
+
if (message.otherParticipants) {
|
1765
|
+
obj.otherParticipants = message.otherParticipants.map((e) => e ? ParticipantInfo.toJSON(e) : undefined);
|
1766
|
+
} else {
|
1767
|
+
obj.otherParticipants = [];
|
1768
|
+
}
|
1683
1769
|
return obj;
|
1684
1770
|
},
|
1685
1771
|
|
@@ -1689,6 +1775,11 @@ export const ReconnectResponse = {
|
|
1689
1775
|
message.clientConfiguration = (object.clientConfiguration !== undefined && object.clientConfiguration !== null)
|
1690
1776
|
? ClientConfiguration.fromPartial(object.clientConfiguration)
|
1691
1777
|
: undefined;
|
1778
|
+
message.room = (object.room !== undefined && object.room !== null) ? Room.fromPartial(object.room) : undefined;
|
1779
|
+
message.participant = (object.participant !== undefined && object.participant !== null)
|
1780
|
+
? ParticipantInfo.fromPartial(object.participant)
|
1781
|
+
: undefined;
|
1782
|
+
message.otherParticipants = object.otherParticipants?.map((e) => ParticipantInfo.fromPartial(e)) || [];
|
1692
1783
|
return message;
|
1693
1784
|
},
|
1694
1785
|
};
|
@@ -3388,6 +3479,122 @@ export const SimulateScenario = {
|
|
3388
3479
|
},
|
3389
3480
|
};
|
3390
3481
|
|
3482
|
+
function createBasePing(): Ping {
|
3483
|
+
return { timestamp: 0, rtt: 0 };
|
3484
|
+
}
|
3485
|
+
|
3486
|
+
export const Ping = {
|
3487
|
+
encode(message: Ping, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
3488
|
+
if (message.timestamp !== 0) {
|
3489
|
+
writer.uint32(8).int64(message.timestamp);
|
3490
|
+
}
|
3491
|
+
if (message.rtt !== 0) {
|
3492
|
+
writer.uint32(16).int64(message.rtt);
|
3493
|
+
}
|
3494
|
+
return writer;
|
3495
|
+
},
|
3496
|
+
|
3497
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): Ping {
|
3498
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
3499
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
3500
|
+
const message = createBasePing();
|
3501
|
+
while (reader.pos < end) {
|
3502
|
+
const tag = reader.uint32();
|
3503
|
+
switch (tag >>> 3) {
|
3504
|
+
case 1:
|
3505
|
+
message.timestamp = longToNumber(reader.int64() as Long);
|
3506
|
+
break;
|
3507
|
+
case 2:
|
3508
|
+
message.rtt = longToNumber(reader.int64() as Long);
|
3509
|
+
break;
|
3510
|
+
default:
|
3511
|
+
reader.skipType(tag & 7);
|
3512
|
+
break;
|
3513
|
+
}
|
3514
|
+
}
|
3515
|
+
return message;
|
3516
|
+
},
|
3517
|
+
|
3518
|
+
fromJSON(object: any): Ping {
|
3519
|
+
return {
|
3520
|
+
timestamp: isSet(object.timestamp) ? Number(object.timestamp) : 0,
|
3521
|
+
rtt: isSet(object.rtt) ? Number(object.rtt) : 0,
|
3522
|
+
};
|
3523
|
+
},
|
3524
|
+
|
3525
|
+
toJSON(message: Ping): unknown {
|
3526
|
+
const obj: any = {};
|
3527
|
+
message.timestamp !== undefined && (obj.timestamp = Math.round(message.timestamp));
|
3528
|
+
message.rtt !== undefined && (obj.rtt = Math.round(message.rtt));
|
3529
|
+
return obj;
|
3530
|
+
},
|
3531
|
+
|
3532
|
+
fromPartial<I extends Exact<DeepPartial<Ping>, I>>(object: I): Ping {
|
3533
|
+
const message = createBasePing();
|
3534
|
+
message.timestamp = object.timestamp ?? 0;
|
3535
|
+
message.rtt = object.rtt ?? 0;
|
3536
|
+
return message;
|
3537
|
+
},
|
3538
|
+
};
|
3539
|
+
|
3540
|
+
function createBasePong(): Pong {
|
3541
|
+
return { lastPingTimestamp: 0, timestamp: 0 };
|
3542
|
+
}
|
3543
|
+
|
3544
|
+
export const Pong = {
|
3545
|
+
encode(message: Pong, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
3546
|
+
if (message.lastPingTimestamp !== 0) {
|
3547
|
+
writer.uint32(8).int64(message.lastPingTimestamp);
|
3548
|
+
}
|
3549
|
+
if (message.timestamp !== 0) {
|
3550
|
+
writer.uint32(16).int64(message.timestamp);
|
3551
|
+
}
|
3552
|
+
return writer;
|
3553
|
+
},
|
3554
|
+
|
3555
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): Pong {
|
3556
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
3557
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
3558
|
+
const message = createBasePong();
|
3559
|
+
while (reader.pos < end) {
|
3560
|
+
const tag = reader.uint32();
|
3561
|
+
switch (tag >>> 3) {
|
3562
|
+
case 1:
|
3563
|
+
message.lastPingTimestamp = longToNumber(reader.int64() as Long);
|
3564
|
+
break;
|
3565
|
+
case 2:
|
3566
|
+
message.timestamp = longToNumber(reader.int64() as Long);
|
3567
|
+
break;
|
3568
|
+
default:
|
3569
|
+
reader.skipType(tag & 7);
|
3570
|
+
break;
|
3571
|
+
}
|
3572
|
+
}
|
3573
|
+
return message;
|
3574
|
+
},
|
3575
|
+
|
3576
|
+
fromJSON(object: any): Pong {
|
3577
|
+
return {
|
3578
|
+
lastPingTimestamp: isSet(object.lastPingTimestamp) ? Number(object.lastPingTimestamp) : 0,
|
3579
|
+
timestamp: isSet(object.timestamp) ? Number(object.timestamp) : 0,
|
3580
|
+
};
|
3581
|
+
},
|
3582
|
+
|
3583
|
+
toJSON(message: Pong): unknown {
|
3584
|
+
const obj: any = {};
|
3585
|
+
message.lastPingTimestamp !== undefined && (obj.lastPingTimestamp = Math.round(message.lastPingTimestamp));
|
3586
|
+
message.timestamp !== undefined && (obj.timestamp = Math.round(message.timestamp));
|
3587
|
+
return obj;
|
3588
|
+
},
|
3589
|
+
|
3590
|
+
fromPartial<I extends Exact<DeepPartial<Pong>, I>>(object: I): Pong {
|
3591
|
+
const message = createBasePong();
|
3592
|
+
message.lastPingTimestamp = object.lastPingTimestamp ?? 0;
|
3593
|
+
message.timestamp = object.timestamp ?? 0;
|
3594
|
+
return message;
|
3595
|
+
},
|
3596
|
+
};
|
3597
|
+
|
3391
3598
|
declare var self: any | undefined;
|
3392
3599
|
declare var window: any | undefined;
|
3393
3600
|
declare var global: any | undefined;
|
package/src/room/RTCEngine.ts
CHANGED
@@ -9,6 +9,7 @@ import {
|
|
9
9
|
DataPacket,
|
10
10
|
DataPacket_Kind,
|
11
11
|
DisconnectReason,
|
12
|
+
ReconnectReason,
|
12
13
|
SpeakerInfo,
|
13
14
|
TrackInfo,
|
14
15
|
UserPacket,
|
@@ -305,7 +306,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
305
306
|
|
306
307
|
let primaryPC = this.publisher.pc;
|
307
308
|
let secondaryPC = this.subscriber.pc;
|
308
|
-
|
309
|
+
let subscriberPrimary = joinResponse.subscriberPrimary;
|
310
|
+
if (subscriberPrimary) {
|
309
311
|
primaryPC = this.subscriber.pc;
|
310
312
|
secondaryPC = this.publisher.pc;
|
311
313
|
// in subscriber primary mode, server side opens sub data channels.
|
@@ -330,7 +332,13 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
330
332
|
if (this.pcState === PCState.Connected) {
|
331
333
|
this.pcState = PCState.Disconnected;
|
332
334
|
|
333
|
-
this.handleDisconnect(
|
335
|
+
this.handleDisconnect(
|
336
|
+
'primary peerconnection',
|
337
|
+
false,
|
338
|
+
subscriberPrimary
|
339
|
+
? ReconnectReason.REASON_SUBSCRIBER_FAILED
|
340
|
+
: ReconnectReason.REASON_PUBLISHER_FAILED,
|
341
|
+
);
|
334
342
|
}
|
335
343
|
}
|
336
344
|
};
|
@@ -338,7 +346,13 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
338
346
|
log.debug(`secondary PC state changed ${secondaryPC.connectionState}`);
|
339
347
|
// also reconnect if secondary peerconnection fails
|
340
348
|
if (secondaryPC.connectionState === 'failed') {
|
341
|
-
this.handleDisconnect(
|
349
|
+
this.handleDisconnect(
|
350
|
+
'secondary peerconnection',
|
351
|
+
false,
|
352
|
+
subscriberPrimary
|
353
|
+
? ReconnectReason.REASON_PUBLISHER_FAILED
|
354
|
+
: ReconnectReason.REASON_SUBSCRIBER_FAILED,
|
355
|
+
);
|
342
356
|
}
|
343
357
|
};
|
344
358
|
|
@@ -405,7 +419,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
405
419
|
};
|
406
420
|
|
407
421
|
this.client.onClose = () => {
|
408
|
-
this.handleDisconnect('signal');
|
422
|
+
this.handleDisconnect('signal', false, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
409
423
|
};
|
410
424
|
|
411
425
|
this.client.onLeave = (leave?: LeaveRequest) => {
|
@@ -676,7 +690,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
676
690
|
// websocket reconnect behavior. if websocket is interrupted, and the PeerConnection
|
677
691
|
// continues to work, we can reconnect to websocket to continue the session
|
678
692
|
// after a number of retries, we'll close and give up permanently
|
679
|
-
private handleDisconnect = (
|
693
|
+
private handleDisconnect = (
|
694
|
+
connection: string,
|
695
|
+
signalEvents: boolean = false,
|
696
|
+
disconnectReason?: ReconnectReason,
|
697
|
+
) => {
|
680
698
|
if (this._isClosed) {
|
681
699
|
return;
|
682
700
|
}
|
@@ -713,12 +731,12 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
713
731
|
|
714
732
|
this.clearReconnectTimeout();
|
715
733
|
this.reconnectTimeout = CriticalTimers.setTimeout(
|
716
|
-
() => this.attemptReconnect(signalEvents),
|
734
|
+
() => this.attemptReconnect(signalEvents, disconnectReason),
|
717
735
|
delay,
|
718
736
|
);
|
719
737
|
};
|
720
738
|
|
721
|
-
private async attemptReconnect(signalEvents: boolean = false) {
|
739
|
+
private async attemptReconnect(signalEvents: boolean = false, reason?: ReconnectReason) {
|
722
740
|
if (this._isClosed) {
|
723
741
|
return;
|
724
742
|
}
|
@@ -740,7 +758,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
740
758
|
if (this.fullReconnectOnNext) {
|
741
759
|
await this.restartConnection(signalEvents);
|
742
760
|
} else {
|
743
|
-
await this.resumeConnection(signalEvents);
|
761
|
+
await this.resumeConnection(signalEvents, reason);
|
744
762
|
}
|
745
763
|
this.clearPendingReconnect();
|
746
764
|
this.fullReconnectOnNext = false;
|
@@ -766,7 +784,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
766
784
|
}
|
767
785
|
|
768
786
|
if (recoverable) {
|
769
|
-
this.handleDisconnect('reconnect', requireSignalEvents);
|
787
|
+
this.handleDisconnect('reconnect', requireSignalEvents, ReconnectReason.REASON_UNKOWN);
|
770
788
|
} else {
|
771
789
|
log.info(
|
772
790
|
`could not recover connection after ${this.reconnectAttempts} attempts, ${
|
@@ -831,7 +849,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
831
849
|
this.emit(EngineEvent.Restarted, joinResponse);
|
832
850
|
}
|
833
851
|
|
834
|
-
private async resumeConnection(
|
852
|
+
private async resumeConnection(
|
853
|
+
emitResuming: boolean = false,
|
854
|
+
reason?: ReconnectReason,
|
855
|
+
): Promise<void> {
|
835
856
|
if (!this.url || !this.token) {
|
836
857
|
// permanent failure, don't attempt reconnection
|
837
858
|
throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
|
@@ -847,7 +868,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
847
868
|
}
|
848
869
|
|
849
870
|
try {
|
850
|
-
const res = await this.client.reconnect(this.url, this.token, this.participantSid);
|
871
|
+
const res = await this.client.reconnect(this.url, this.token, this.participantSid, reason);
|
851
872
|
if (res) {
|
852
873
|
const rtcConfig = this.makeRTCConfiguration(res);
|
853
874
|
this.publisher.pc.setConfiguration(rtcConfig);
|
@@ -1001,7 +1022,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1001
1022
|
|
1002
1023
|
const negotiationTimeout = setTimeout(() => {
|
1003
1024
|
reject('negotiation timed out');
|
1004
|
-
this.handleDisconnect('negotiation');
|
1025
|
+
this.handleDisconnect('negotiation', false, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
1005
1026
|
}, this.peerConnectionTimeout);
|
1006
1027
|
|
1007
1028
|
const cleanup = () => {
|
@@ -1022,7 +1043,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1022
1043
|
if (e instanceof NegotiationError) {
|
1023
1044
|
this.fullReconnectOnNext = true;
|
1024
1045
|
}
|
1025
|
-
this.handleDisconnect('negotiation');
|
1046
|
+
this.handleDisconnect('negotiation', false, ReconnectReason.REASON_UNKOWN);
|
1026
1047
|
});
|
1027
1048
|
});
|
1028
1049
|
}
|
@@ -1060,7 +1081,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1060
1081
|
// in case the engine is currently reconnecting, attempt a reconnect immediately after the browser state has changed to 'onLine'
|
1061
1082
|
if (this.client.isReconnecting) {
|
1062
1083
|
this.clearReconnectTimeout();
|
1063
|
-
this.attemptReconnect(true);
|
1084
|
+
this.attemptReconnect(true, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
|
1064
1085
|
}
|
1065
1086
|
};
|
1066
1087
|
|