Skip to content

Commit b71ec61

Browse files
authored
Add reconnect reason and signal rtt calculation (#573)
* Add reconnect reason and signal rtt caculation * changeset
1 parent c140888 commit b71ec61

File tree

5 files changed

+335
-19
lines changed

5 files changed

+335
-19
lines changed

.changeset/neat-moles-wink.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'livekit-client': patch
3+
---
4+
5+
Add reconnect reason and signal rtt calculation

src/api/SignalClient.ts

+34-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ClientInfo,
66
DisconnectReason,
77
ParticipantInfo,
8+
ReconnectReason,
89
Room,
910
SpeakerInfo,
1011
VideoLayer,
@@ -40,6 +41,9 @@ interface ConnectOpts {
4041
/** internal */
4142
reconnect?: boolean;
4243

44+
/** internal */
45+
reconnectReason?: number;
46+
4347
/** internal */
4448
sid?: string;
4549

@@ -89,6 +93,9 @@ export class SignalClient {
8993

9094
useJSON: boolean;
9195

96+
/** signal rtt in milliseconds */
97+
rtt: number = 0;
98+
9299
/** simulate signaling latency by delaying messages */
93100
signalLatency?: number;
94101

@@ -166,7 +173,12 @@ export class SignalClient {
166173
return res as JoinResponse;
167174
}
168175

169-
async reconnect(url: string, token: string, sid?: string): Promise<ReconnectResponse | void> {
176+
async reconnect(
177+
url: string,
178+
token: string,
179+
sid?: string,
180+
reason?: ReconnectReason,
181+
): Promise<ReconnectResponse | void> {
170182
if (!this.options) {
171183
log.warn('attempted to reconnect without signal options being set, ignoring');
172184
return;
@@ -175,7 +187,12 @@ export class SignalClient {
175187
// clear ping interval and restart it once reconnected
176188
this.clearPingInterval();
177189

178-
const res = await this.connect(url, token, { ...this.options, reconnect: true, sid });
190+
const res = await this.connect(url, token, {
191+
...this.options,
192+
reconnect: true,
193+
sid,
194+
reconnectReason: reason,
195+
});
179196
return res;
180197
}
181198

@@ -440,10 +457,18 @@ export class SignalClient {
440457
}
441458

442459
sendPing() {
460+
/** send both of ping and pingReq for compatibility to old and new server */
443461
this.sendRequest({
444462
$case: 'ping',
445463
ping: Date.now(),
446464
});
465+
this.sendRequest({
466+
$case: 'pingReq',
467+
pingReq: {
468+
timestamp: Date.now(),
469+
rtt: this.rtt,
470+
},
471+
});
447472
}
448473

449474
async sendLeave() {
@@ -563,6 +588,9 @@ export class SignalClient {
563588
}
564589
} else if (msg.$case === 'pong') {
565590
this.resetPingTimeout();
591+
} else if (msg.$case === 'pongResp') {
592+
this.rtt = Date.now() - msg.pongResp.lastPingTimestamp;
593+
this.clearPingTimeout();
566594
} else {
567595
log.debug('unsupported message', msg);
568596
}
@@ -698,6 +726,10 @@ function createConnectionParams(token: string, info: ClientInfo, opts: ConnectOp
698726
params.set('adaptive_stream', '1');
699727
}
700728

729+
if (opts.reconnectReason) {
730+
params.set('reconnect_reason', opts.reconnectReason.toString());
731+
}
732+
701733
// @ts-ignore
702734
if (navigator.connection?.type) {
703735
// @ts-ignore

src/proto/livekit_models.ts

+51
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,57 @@ export function disconnectReasonToJSON(object: DisconnectReason): string {
287287
}
288288
}
289289

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+
290341
export interface Room {
291342
sid: string;
292343
name: string;

0 commit comments

Comments
 (0)