@webex/plugin-meetings 3.0.0-next.23 → 3.0.0-next.25
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +116 -109
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.d.ts +8 -0
- package/dist/meetings/index.js +20 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +1 -0
- package/dist/reachability/clusterReachability.js +29 -15
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.d.ts +4 -0
- package/dist/reachability/index.js +18 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/util.d.ts +7 -0
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/config.ts +1 -0
- package/src/meeting/index.ts +19 -15
- package/src/meetings/index.ts +18 -0
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/util.ts +21 -0
- package/test/unit/spec/meeting/index.js +7 -18
- package/test/unit/spec/meetings/index.js +13 -0
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/util.ts +32 -2
|
@@ -2,7 +2,7 @@ import {Defer} from '@webex/common';
|
|
|
2
2
|
|
|
3
3
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
4
4
|
import {ClusterNode} from './request';
|
|
5
|
-
import {convertStunUrlToTurn} from './util';
|
|
5
|
+
import {convertStunUrlToTurn, convertStunUrlToTurnTls} from './util';
|
|
6
6
|
|
|
7
7
|
import {ICE_GATHERING_STATE, CONNECTION_STATE} from '../constants';
|
|
8
8
|
|
|
@@ -29,6 +29,7 @@ export type ClusterReachabilityResult = {
|
|
|
29
29
|
export class ClusterReachability {
|
|
30
30
|
private numUdpUrls: number;
|
|
31
31
|
private numTcpUrls: number;
|
|
32
|
+
private numXTlsUrls: number;
|
|
32
33
|
private result: ClusterReachabilityResult;
|
|
33
34
|
private pc?: RTCPeerConnection;
|
|
34
35
|
private defer: Defer; // this defer is resolved once reachability checks for this cluster are completed
|
|
@@ -46,6 +47,7 @@ export class ClusterReachability {
|
|
|
46
47
|
this.isVideoMesh = clusterInfo.isVideoMesh;
|
|
47
48
|
this.numUdpUrls = clusterInfo.udp.length;
|
|
48
49
|
this.numTcpUrls = clusterInfo.tcp.length;
|
|
50
|
+
this.numXTlsUrls = clusterInfo.xtls.length;
|
|
49
51
|
|
|
50
52
|
this.pc = this.createPeerConnection(clusterInfo);
|
|
51
53
|
|
|
@@ -94,8 +96,16 @@ export class ClusterReachability {
|
|
|
94
96
|
};
|
|
95
97
|
});
|
|
96
98
|
|
|
99
|
+
const turnTlsIceServers = cluster.xtls.map((urlString: string) => {
|
|
100
|
+
return {
|
|
101
|
+
username: 'webexturnreachuser',
|
|
102
|
+
credential: 'webexturnreachpwd',
|
|
103
|
+
urls: [convertStunUrlToTurnTls(urlString)],
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
|
|
97
107
|
return {
|
|
98
|
-
iceServers: [...udpIceServers, ...tcpIceServers],
|
|
108
|
+
iceServers: [...udpIceServers, ...tcpIceServers, ...turnTlsIceServers],
|
|
99
109
|
iceCandidatePoolSize: 0,
|
|
100
110
|
iceTransportPolicy: 'all',
|
|
101
111
|
};
|
|
@@ -194,7 +204,7 @@ export class ClusterReachability {
|
|
|
194
204
|
* @returns {boolean} true if we have all results, false otherwise
|
|
195
205
|
*/
|
|
196
206
|
private haveWeGotAllResults(): boolean {
|
|
197
|
-
return ['udp', 'tcp'].every(
|
|
207
|
+
return ['udp', 'tcp', 'xtls'].every(
|
|
198
208
|
(protocol) =>
|
|
199
209
|
this.result[protocol].result === 'reachable' || this.result[protocol].result === 'untested'
|
|
200
210
|
);
|
|
@@ -207,7 +217,7 @@ export class ClusterReachability {
|
|
|
207
217
|
* @param {number} latency
|
|
208
218
|
* @returns {void}
|
|
209
219
|
*/
|
|
210
|
-
private storeLatencyResult(protocol: 'udp' | 'tcp', latency: number) {
|
|
220
|
+
private storeLatencyResult(protocol: 'udp' | 'tcp' | 'xtls', latency: number) {
|
|
211
221
|
const result = this.result[protocol];
|
|
212
222
|
|
|
213
223
|
if (result.latencyInMilliseconds === undefined) {
|
|
@@ -227,6 +237,7 @@ export class ClusterReachability {
|
|
|
227
237
|
*/
|
|
228
238
|
private registerIceCandidateListener() {
|
|
229
239
|
this.pc.onicecandidate = (e) => {
|
|
240
|
+
const TURN_TLS_PORT = 443;
|
|
230
241
|
const CANDIDATE_TYPES = {
|
|
231
242
|
SERVER_REFLEXIVE: 'srflx',
|
|
232
243
|
RELAY: 'relay',
|
|
@@ -239,7 +250,8 @@ export class ClusterReachability {
|
|
|
239
250
|
}
|
|
240
251
|
|
|
241
252
|
if (e.candidate.type === CANDIDATE_TYPES.RELAY) {
|
|
242
|
-
|
|
253
|
+
const protocol = e.candidate.port === TURN_TLS_PORT ? 'xtls' : 'tcp';
|
|
254
|
+
this.storeLatencyResult(protocol, this.getElapsedTime());
|
|
243
255
|
// we don't add public IP for TCP, because in the case of relay candidates
|
|
244
256
|
// e.candidate.address is the TURN server address, not the client's public IP
|
|
245
257
|
}
|
|
@@ -275,6 +287,9 @@ export class ClusterReachability {
|
|
|
275
287
|
this.result.tcp = {
|
|
276
288
|
result: this.numTcpUrls > 0 ? 'unreachable' : 'untested',
|
|
277
289
|
};
|
|
290
|
+
this.result.xtls = {
|
|
291
|
+
result: this.numXTlsUrls > 0 ? 'unreachable' : 'untested',
|
|
292
|
+
};
|
|
278
293
|
|
|
279
294
|
try {
|
|
280
295
|
const offer = await this.pc.createOffer({offerToReceiveAudio: true});
|
|
@@ -22,10 +22,14 @@ export type ReachabilityMetrics = {
|
|
|
22
22
|
reachability_public_udp_failed: number;
|
|
23
23
|
reachability_public_tcp_success: number;
|
|
24
24
|
reachability_public_tcp_failed: number;
|
|
25
|
+
reachability_public_xtls_success: number;
|
|
26
|
+
reachability_public_xtls_failed: number;
|
|
25
27
|
reachability_vmn_udp_success: number;
|
|
26
28
|
reachability_vmn_udp_failed: number;
|
|
27
29
|
reachability_vmn_tcp_success: number;
|
|
28
30
|
reachability_vmn_tcp_failed: number;
|
|
31
|
+
reachability_vmn_xtls_success: number;
|
|
32
|
+
reachability_vmn_xtls_failed: number;
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
/**
|
|
@@ -141,10 +145,14 @@ export default class Reachability {
|
|
|
141
145
|
reachability_public_udp_failed: 0,
|
|
142
146
|
reachability_public_tcp_success: 0,
|
|
143
147
|
reachability_public_tcp_failed: 0,
|
|
148
|
+
reachability_public_xtls_success: 0,
|
|
149
|
+
reachability_public_xtls_failed: 0,
|
|
144
150
|
reachability_vmn_udp_success: 0,
|
|
145
151
|
reachability_vmn_udp_failed: 0,
|
|
146
152
|
reachability_vmn_tcp_success: 0,
|
|
147
153
|
reachability_vmn_tcp_failed: 0,
|
|
154
|
+
reachability_vmn_xtls_success: 0,
|
|
155
|
+
reachability_vmn_xtls_failed: 0,
|
|
148
156
|
};
|
|
149
157
|
|
|
150
158
|
const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {
|
|
@@ -156,6 +164,10 @@ export default class Reachability {
|
|
|
156
164
|
const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';
|
|
157
165
|
stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;
|
|
158
166
|
}
|
|
167
|
+
if (result.xtls && result.xtls.result !== 'untested') {
|
|
168
|
+
const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';
|
|
169
|
+
stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;
|
|
170
|
+
}
|
|
159
171
|
};
|
|
160
172
|
|
|
161
173
|
try {
|
|
@@ -338,7 +350,10 @@ export default class Reachability {
|
|
|
338
350
|
LoggerProxy.logger.log(
|
|
339
351
|
`Reachability:index#performReachabilityChecks --> doing UDP${
|
|
340
352
|
// @ts-ignore
|
|
341
|
-
this.webex.config.meetings.experimental.enableTcpReachability ? '
|
|
353
|
+
this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''
|
|
354
|
+
}${
|
|
355
|
+
// @ts-ignore
|
|
356
|
+
this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''
|
|
342
357
|
} reachability checks`
|
|
343
358
|
);
|
|
344
359
|
|
|
@@ -354,6 +369,14 @@ export default class Reachability {
|
|
|
354
369
|
cluster.tcp = [];
|
|
355
370
|
}
|
|
356
371
|
|
|
372
|
+
const includeTlsReachability =
|
|
373
|
+
// @ts-ignore
|
|
374
|
+
this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;
|
|
375
|
+
|
|
376
|
+
if (!includeTlsReachability) {
|
|
377
|
+
cluster.xtls = [];
|
|
378
|
+
}
|
|
379
|
+
|
|
357
380
|
this.clusterReachability[key] = new ClusterReachability(key, cluster);
|
|
358
381
|
|
|
359
382
|
return this.clusterReachability[key].start().then((result) => {
|
package/src/reachability/util.ts
CHANGED
|
@@ -22,3 +22,24 @@ export function convertStunUrlToTurn(stunUrl: string, protocol: 'udp' | 'tcp') {
|
|
|
22
22
|
|
|
23
23
|
return url.toString();
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Converts a stun url to a turns url
|
|
28
|
+
*
|
|
29
|
+
* @param {string} stunUrl url of a stun server
|
|
30
|
+
* @returns {string} url of a turns server
|
|
31
|
+
*/
|
|
32
|
+
export function convertStunUrlToTurnTls(stunUrl: string) {
|
|
33
|
+
// stunUrl looks like this: "stun:external-media1.public.wjfkm-a-15.prod.infra.webex.com:443"
|
|
34
|
+
// and we need it to be like this: "turns:external-media1.public.wjfkm-a-15.prod.infra.webex.com:443?transport=tcp"
|
|
35
|
+
const url = new URL(stunUrl);
|
|
36
|
+
|
|
37
|
+
if (url.protocol !== 'stun:') {
|
|
38
|
+
throw new Error(`Not a STUN URL: ${stunUrl}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
url.protocol = 'turns:';
|
|
42
|
+
url.searchParams.append('transport', 'tcp');
|
|
43
|
+
|
|
44
|
+
return url.toString();
|
|
45
|
+
}
|
|
@@ -1011,15 +1011,14 @@ describe('plugin-meetings', () => {
|
|
|
1011
1011
|
});
|
|
1012
1012
|
|
|
1013
1013
|
describe('transcription events', () => {
|
|
1014
|
+
beforeEach(() => {
|
|
1015
|
+
meeting.trigger = sinon.stub();
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1014
1018
|
it('should trigger meeting:caption-received event', () => {
|
|
1015
1019
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
1016
1020
|
assert.calledWith(
|
|
1017
|
-
|
|
1018
|
-
sinon.match.instanceOf(Meeting),
|
|
1019
|
-
{
|
|
1020
|
-
file: 'meeting/index',
|
|
1021
|
-
function: 'setUpVoiceaListeners',
|
|
1022
|
-
},
|
|
1021
|
+
meeting.trigger,
|
|
1023
1022
|
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
1024
1023
|
);
|
|
1025
1024
|
});
|
|
@@ -1027,12 +1026,7 @@ describe('plugin-meetings', () => {
|
|
|
1027
1026
|
it('should trigger meeting:receiveTranscription:started event', () => {
|
|
1028
1027
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]({});
|
|
1029
1028
|
assert.calledWith(
|
|
1030
|
-
|
|
1031
|
-
sinon.match.instanceOf(Meeting),
|
|
1032
|
-
{
|
|
1033
|
-
file: 'meeting/index',
|
|
1034
|
-
function: 'setUpVoiceaListeners',
|
|
1035
|
-
},
|
|
1029
|
+
meeting.trigger,
|
|
1036
1030
|
EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION
|
|
1037
1031
|
);
|
|
1038
1032
|
});
|
|
@@ -1040,12 +1034,7 @@ describe('plugin-meetings', () => {
|
|
|
1040
1034
|
it('should trigger meeting:caption-received event', () => {
|
|
1041
1035
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
1042
1036
|
assert.calledWith(
|
|
1043
|
-
|
|
1044
|
-
sinon.match.instanceOf(Meeting),
|
|
1045
|
-
{
|
|
1046
|
-
file: 'meeting/index',
|
|
1047
|
-
function: 'setUpVoiceaListeners',
|
|
1048
|
-
},
|
|
1037
|
+
meeting.trigger,
|
|
1049
1038
|
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
1050
1039
|
);
|
|
1051
1040
|
});
|
|
@@ -253,6 +253,19 @@ describe('plugin-meetings', () => {
|
|
|
253
253
|
});
|
|
254
254
|
});
|
|
255
255
|
|
|
256
|
+
describe('#_toggleTlsReachability', () => {
|
|
257
|
+
it('should have _toggleTlsReachability', () => {
|
|
258
|
+
assert.equal(typeof webex.meetings._toggleTlsReachability, 'function');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
describe('success', () => {
|
|
262
|
+
it('should update meetings to do TLS reachability', () => {
|
|
263
|
+
webex.meetings._toggleTlsReachability(true);
|
|
264
|
+
assert.equal(webex.meetings.config.experimental.enableTlsReachability, true);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
256
269
|
describe('Public API Contracts', () => {
|
|
257
270
|
describe('#register', () => {
|
|
258
271
|
it('emits an event and resolves when register succeeds', async () => {
|
|
@@ -4,7 +4,7 @@ import sinon from 'sinon';
|
|
|
4
4
|
import testUtils from '../../../utils/testUtils';
|
|
5
5
|
|
|
6
6
|
// packages/@webex/plugin-meetings/test/unit/spec/reachability/clusterReachability.ts
|
|
7
|
-
import {
|
|
7
|
+
import {ClusterReachability} from '@webex/plugin-meetings/src/reachability/clusterReachability'; // replace with actual path
|
|
8
8
|
|
|
9
9
|
describe('ClusterReachability', () => {
|
|
10
10
|
let previousRTCPeerConnection;
|
|
@@ -28,9 +28,8 @@ describe('ClusterReachability', () => {
|
|
|
28
28
|
isVideoMesh: false,
|
|
29
29
|
udp: ['stun:udp1', 'stun:udp2'],
|
|
30
30
|
tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
|
|
31
|
-
xtls: ['xtls1', 'xtls2'],
|
|
31
|
+
xtls: ['stun:xtls1.webex.com', 'stun:xtls2.webex.com:443'],
|
|
32
32
|
});
|
|
33
|
-
|
|
34
33
|
});
|
|
35
34
|
|
|
36
35
|
afterEach(() => {
|
|
@@ -50,8 +49,26 @@ describe('ClusterReachability', () => {
|
|
|
50
49
|
iceServers: [
|
|
51
50
|
{username: '', credential: '', urls: ['stun:udp1']},
|
|
52
51
|
{username: '', credential: '', urls: ['stun:udp2']},
|
|
53
|
-
{
|
|
54
|
-
|
|
52
|
+
{
|
|
53
|
+
username: 'webexturnreachuser',
|
|
54
|
+
credential: 'webexturnreachpwd',
|
|
55
|
+
urls: ['turn:tcp1.webex.com?transport=tcp'],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
username: 'webexturnreachuser',
|
|
59
|
+
credential: 'webexturnreachpwd',
|
|
60
|
+
urls: ['turn:tcp2.webex.com:5004?transport=tcp'],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
username: 'webexturnreachuser',
|
|
64
|
+
credential: 'webexturnreachpwd',
|
|
65
|
+
urls: ['turns:xtls1.webex.com?transport=tcp'],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
username: 'webexturnreachuser',
|
|
69
|
+
credential: 'webexturnreachpwd',
|
|
70
|
+
urls: ['turns:xtls2.webex.com:443?transport=tcp'],
|
|
71
|
+
},
|
|
55
72
|
],
|
|
56
73
|
iceCandidatePoolSize: 0,
|
|
57
74
|
iceTransportPolicy: 'all',
|
|
@@ -79,7 +96,7 @@ describe('ClusterReachability', () => {
|
|
|
79
96
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
80
97
|
udp: {result: 'untested'},
|
|
81
98
|
tcp: {result: 'untested'},
|
|
82
|
-
xtls: {result: 'untested'}
|
|
99
|
+
xtls: {result: 'untested'},
|
|
83
100
|
});
|
|
84
101
|
});
|
|
85
102
|
|
|
@@ -92,7 +109,7 @@ describe('ClusterReachability', () => {
|
|
|
92
109
|
|
|
93
110
|
afterEach(() => {
|
|
94
111
|
clock.restore();
|
|
95
|
-
})
|
|
112
|
+
});
|
|
96
113
|
|
|
97
114
|
it('should initiate the ICE gathering process', async () => {
|
|
98
115
|
const promise = clusterReachability.start();
|
|
@@ -107,11 +124,11 @@ describe('ClusterReachability', () => {
|
|
|
107
124
|
assert.calledOnceWithExactly(fakePeerConnection.createOffer, {offerToReceiveAudio: true});
|
|
108
125
|
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
109
126
|
|
|
110
|
-
await clock.tickAsync(3000)
|
|
127
|
+
await clock.tickAsync(3000); // move the clock so that reachability times out
|
|
111
128
|
await promise;
|
|
112
129
|
});
|
|
113
130
|
|
|
114
|
-
it('resolves and has correct result as soon as it finds that
|
|
131
|
+
it('resolves and has correct result as soon as it finds that all udp, tcp and tls are reachable', async () => {
|
|
115
132
|
const promise = clusterReachability.start();
|
|
116
133
|
|
|
117
134
|
await clock.tickAsync(100);
|
|
@@ -120,12 +137,17 @@ describe('ClusterReachability', () => {
|
|
|
120
137
|
await clock.tickAsync(100);
|
|
121
138
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
|
122
139
|
|
|
140
|
+
await clock.tickAsync(100);
|
|
141
|
+
fakePeerConnection.onicecandidate({
|
|
142
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
|
143
|
+
});
|
|
144
|
+
|
|
123
145
|
await promise;
|
|
124
146
|
|
|
125
147
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
126
148
|
udp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['somePublicIp']},
|
|
127
149
|
tcp: {result: 'reachable', latencyInMilliseconds: 200},
|
|
128
|
-
xtls: {result: '
|
|
150
|
+
xtls: {result: 'reachable', latencyInMilliseconds: 300},
|
|
129
151
|
});
|
|
130
152
|
});
|
|
131
153
|
|
|
@@ -139,7 +161,7 @@ describe('ClusterReachability', () => {
|
|
|
139
161
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
140
162
|
udp: {result: 'unreachable'},
|
|
141
163
|
tcp: {result: 'unreachable'},
|
|
142
|
-
xtls: {result: '
|
|
164
|
+
xtls: {result: 'unreachable'},
|
|
143
165
|
});
|
|
144
166
|
});
|
|
145
167
|
|
|
@@ -148,7 +170,7 @@ describe('ClusterReachability', () => {
|
|
|
148
170
|
isVideoMesh: true,
|
|
149
171
|
udp: ['stun:udp1', 'stun:udp2'],
|
|
150
172
|
tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
|
|
151
|
-
xtls: ['xtls1', '
|
|
173
|
+
xtls: ['stun:xtls1.webex.com', 'stun:xtls1.webex.com:443'],
|
|
152
174
|
});
|
|
153
175
|
|
|
154
176
|
const promise = clusterReachability.start();
|
|
@@ -160,7 +182,7 @@ describe('ClusterReachability', () => {
|
|
|
160
182
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
161
183
|
udp: {result: 'unreachable'},
|
|
162
184
|
tcp: {result: 'unreachable'},
|
|
163
|
-
xtls: {result: '
|
|
185
|
+
xtls: {result: 'unreachable'},
|
|
164
186
|
});
|
|
165
187
|
});
|
|
166
188
|
|
|
@@ -176,7 +198,7 @@ describe('ClusterReachability', () => {
|
|
|
176
198
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
177
199
|
udp: {result: 'unreachable'},
|
|
178
200
|
tcp: {result: 'unreachable'},
|
|
179
|
-
xtls: {result: '
|
|
201
|
+
xtls: {result: 'unreachable'},
|
|
180
202
|
});
|
|
181
203
|
});
|
|
182
204
|
|
|
@@ -194,7 +216,7 @@ describe('ClusterReachability', () => {
|
|
|
194
216
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
195
217
|
udp: {result: 'reachable', latencyInMilliseconds: 30, clientMediaIPs: ['somePublicIp1']},
|
|
196
218
|
tcp: {result: 'unreachable'},
|
|
197
|
-
xtls: {result: '
|
|
219
|
+
xtls: {result: 'unreachable'},
|
|
198
220
|
});
|
|
199
221
|
});
|
|
200
222
|
|
|
@@ -211,15 +233,19 @@ describe('ClusterReachability', () => {
|
|
|
211
233
|
await clock.tickAsync(10);
|
|
212
234
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp3'}});
|
|
213
235
|
|
|
214
|
-
await clock.tickAsync(3000)
|
|
236
|
+
await clock.tickAsync(3000); // move the clock so that reachability times out
|
|
215
237
|
|
|
216
238
|
await promise;
|
|
217
239
|
|
|
218
240
|
// latency should be from only the first candidates, but the clientMediaIps should be from all UDP candidates (not TCP)
|
|
219
241
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
220
|
-
udp: {
|
|
242
|
+
udp: {
|
|
243
|
+
result: 'reachable',
|
|
244
|
+
latencyInMilliseconds: 10,
|
|
245
|
+
clientMediaIPs: ['somePublicIp1', 'somePublicIp2', 'somePublicIp3'],
|
|
246
|
+
},
|
|
221
247
|
tcp: {result: 'unreachable'},
|
|
222
|
-
xtls: {result: '
|
|
248
|
+
xtls: {result: 'unreachable'},
|
|
223
249
|
});
|
|
224
250
|
});
|
|
225
251
|
|
|
@@ -236,7 +262,7 @@ describe('ClusterReachability', () => {
|
|
|
236
262
|
await clock.tickAsync(10);
|
|
237
263
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp3'}});
|
|
238
264
|
|
|
239
|
-
await clock.tickAsync(3000)
|
|
265
|
+
await clock.tickAsync(3000); // move the clock so that reachability times out
|
|
240
266
|
|
|
241
267
|
await promise;
|
|
242
268
|
|
|
@@ -244,7 +270,38 @@ describe('ClusterReachability', () => {
|
|
|
244
270
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
245
271
|
udp: {result: 'unreachable'},
|
|
246
272
|
tcp: {result: 'reachable', latencyInMilliseconds: 10},
|
|
247
|
-
xtls: {result: '
|
|
273
|
+
xtls: {result: 'unreachable'},
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should store latency only for the first tls relay candidate', async () => {
|
|
278
|
+
const promise = clusterReachability.start();
|
|
279
|
+
|
|
280
|
+
await clock.tickAsync(10);
|
|
281
|
+
fakePeerConnection.onicecandidate({
|
|
282
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp1', port: 443},
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// generate more candidates
|
|
286
|
+
await clock.tickAsync(10);
|
|
287
|
+
fakePeerConnection.onicecandidate({
|
|
288
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp2', port: 443},
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await clock.tickAsync(10);
|
|
292
|
+
fakePeerConnection.onicecandidate({
|
|
293
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp3', port: 443},
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
await clock.tickAsync(3000); // move the clock so that reachability times out
|
|
297
|
+
|
|
298
|
+
await promise;
|
|
299
|
+
|
|
300
|
+
// latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
|
|
301
|
+
assert.deepEqual(clusterReachability.getResult(), {
|
|
302
|
+
udp: {result: 'unreachable'},
|
|
303
|
+
tcp: {result: 'unreachable'},
|
|
304
|
+
xtls: {result: 'reachable', latencyInMilliseconds: 10},
|
|
248
305
|
});
|
|
249
306
|
});
|
|
250
307
|
|
|
@@ -266,13 +323,20 @@ describe('ClusterReachability', () => {
|
|
|
266
323
|
|
|
267
324
|
// send also a relay candidate so that the reachability check finishes
|
|
268
325
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
|
326
|
+
fakePeerConnection.onicecandidate({
|
|
327
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
|
328
|
+
});
|
|
269
329
|
|
|
270
330
|
await promise;
|
|
271
331
|
|
|
272
332
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
273
|
-
udp: {
|
|
333
|
+
udp: {
|
|
334
|
+
result: 'reachable',
|
|
335
|
+
latencyInMilliseconds: 10,
|
|
336
|
+
clientMediaIPs: ['somePublicIp1', 'somePublicIp2'],
|
|
337
|
+
},
|
|
274
338
|
tcp: {result: 'reachable', latencyInMilliseconds: 40},
|
|
275
|
-
xtls: {result: '
|
|
339
|
+
xtls: {result: 'reachable', latencyInMilliseconds: 40},
|
|
276
340
|
});
|
|
277
341
|
});
|
|
278
342
|
});
|