@webex/plugin-meetings 2.60.0-next.9 → 2.60.1-next.1
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/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.d.ts +2 -0
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.d.ts +27 -0
- package/dist/interceptors/locusRetry.js +94 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +6 -2
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.d.ts +1 -11
- package/dist/meetings/index.js +4 -3
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +109 -0
- package/dist/reachability/clusterReachability.js +357 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.d.ts +32 -121
- package/dist/reachability/index.js +173 -459
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/util.d.ts +8 -0
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/statsAnalyzer/index.d.ts +22 -0
- package/dist/statsAnalyzer/index.js +60 -0
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +4 -0
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +25 -22
- package/src/config.ts +1 -0
- package/src/index.ts +4 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/meeting/index.ts +10 -2
- package/src/meetings/index.ts +4 -3
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +124 -421
- package/src/reachability/util.ts +24 -0
- package/src/statsAnalyzer/index.ts +64 -1
- package/src/statsAnalyzer/mqaUtil.ts +4 -0
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/meeting/index.js +8 -1
- package/test/unit/spec/meetings/index.js +28 -25
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +159 -226
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/roap/request.ts +26 -3
- package/test/unit/spec/stats-analyzer/index.js +100 -20
|
@@ -9,11 +9,10 @@ exports.default = void 0;
|
|
|
9
9
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
10
10
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
11
11
|
var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
|
|
12
|
-
var
|
|
12
|
+
var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
|
|
13
13
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
14
14
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
15
|
-
var
|
|
16
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
15
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
17
16
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
18
17
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
19
18
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
@@ -23,22 +22,16 @@ var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy")
|
|
|
23
22
|
var _util = _interopRequireDefault(require("../meeting/util"));
|
|
24
23
|
var _constants = require("../constants");
|
|
25
24
|
var _request = _interopRequireDefault(require("./request"));
|
|
25
|
+
var _clusterReachability = require("./clusterReachability");
|
|
26
26
|
/*!
|
|
27
27
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
29
|
/* eslint-disable class-methods-use-this */
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// result for a specific transport protocol (like udp or tcp)
|
|
37
|
-
|
|
38
|
-
// reachability result for a specifc media cluster
|
|
39
|
-
|
|
30
|
+
/**
|
|
31
|
+
* This is the type that matches what backend expects us to send to them. It is a bit weird, because
|
|
32
|
+
* it uses strings instead of booleans and numbers, but that's what they require.
|
|
33
|
+
*/
|
|
40
34
|
// this is the type that is required by the backend when we send them reachability results
|
|
41
|
-
|
|
42
35
|
// this is the type used by Reachability class internally and stored in local storage
|
|
43
36
|
/**
|
|
44
37
|
* @class Reachability
|
|
@@ -55,7 +48,7 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
55
48
|
(0, _defineProperty2.default)(this, "namespace", _constants.REACHABILITY.namespace);
|
|
56
49
|
(0, _defineProperty2.default)(this, "webex", void 0);
|
|
57
50
|
(0, _defineProperty2.default)(this, "reachabilityRequest", void 0);
|
|
58
|
-
(0, _defineProperty2.default)(this, "
|
|
51
|
+
(0, _defineProperty2.default)(this, "clusterReachability", void 0);
|
|
59
52
|
this.webex = webex;
|
|
60
53
|
|
|
61
54
|
/**
|
|
@@ -66,22 +59,13 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
66
59
|
* @memberof Reachability
|
|
67
60
|
*/
|
|
68
61
|
this.reachabilityRequest = new _request.default(this.webex);
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* internal object of clusters latency results
|
|
72
|
-
* @instance
|
|
73
|
-
* @type {object}
|
|
74
|
-
* @private
|
|
75
|
-
* @memberof Reachability
|
|
76
|
-
*/
|
|
77
|
-
this.clusterLatencyResults = {};
|
|
62
|
+
this.clusterReachability = {};
|
|
78
63
|
}
|
|
79
64
|
|
|
80
65
|
/**
|
|
81
|
-
*
|
|
82
|
-
* @returns {
|
|
66
|
+
* Gets a list of media clusters from the backend and performs reachability checks on all the clusters
|
|
67
|
+
* @returns {Promise<ReachabilityResults>} reachability results
|
|
83
68
|
* @public
|
|
84
|
-
* @async
|
|
85
69
|
* @memberof Reachability
|
|
86
70
|
*/
|
|
87
71
|
(0, _createClass2.default)(Reachability, [{
|
|
@@ -92,45 +76,41 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
92
76
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
93
77
|
while (1) switch (_context.prev = _context.next) {
|
|
94
78
|
case 0:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// Remove stored reachability results to ensure no stale data
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
_context.next = 3;
|
|
79
|
+
_context.next = 2;
|
|
100
80
|
return this.webex.boundedStorage.del(this.namespace, _constants.REACHABILITY.localStorageResult);
|
|
101
|
-
case
|
|
102
|
-
_context.next =
|
|
81
|
+
case 2:
|
|
82
|
+
_context.next = 4;
|
|
103
83
|
return this.webex.boundedStorage.del(this.namespace, _constants.REACHABILITY.localStorageJoinCookie);
|
|
104
|
-
case
|
|
105
|
-
_context.prev =
|
|
106
|
-
_context.next =
|
|
84
|
+
case 4:
|
|
85
|
+
_context.prev = 4;
|
|
86
|
+
_context.next = 7;
|
|
107
87
|
return this.reachabilityRequest.getClusters(_util.default.getIpVersion(this.webex));
|
|
108
|
-
case
|
|
88
|
+
case 7:
|
|
109
89
|
_yield$this$reachabil = _context.sent;
|
|
110
90
|
clusters = _yield$this$reachabil.clusters;
|
|
111
91
|
joinCookie = _yield$this$reachabil.joinCookie;
|
|
112
|
-
_context.next =
|
|
113
|
-
return this.
|
|
114
|
-
case
|
|
92
|
+
_context.next = 12;
|
|
93
|
+
return this.performReachabilityChecks(clusters);
|
|
94
|
+
case 12:
|
|
115
95
|
results = _context.sent;
|
|
116
|
-
_context.next =
|
|
96
|
+
_context.next = 15;
|
|
117
97
|
return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageResult, (0, _stringify.default)(results));
|
|
118
|
-
case
|
|
119
|
-
_context.next =
|
|
98
|
+
case 15:
|
|
99
|
+
_context.next = 17;
|
|
120
100
|
return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageJoinCookie, (0, _stringify.default)(joinCookie));
|
|
121
|
-
case
|
|
101
|
+
case 17:
|
|
122
102
|
_loggerProxy.default.logger.log('Reachability:index#gatherReachability --> Reachability checks completed');
|
|
123
103
|
return _context.abrupt("return", results);
|
|
124
|
-
case
|
|
125
|
-
_context.prev =
|
|
126
|
-
_context.t0 = _context["catch"](
|
|
127
|
-
_loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error
|
|
104
|
+
case 21:
|
|
105
|
+
_context.prev = 21;
|
|
106
|
+
_context.t0 = _context["catch"](4);
|
|
107
|
+
_loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error:", _context.t0);
|
|
128
108
|
return _context.abrupt("return", {});
|
|
129
|
-
case
|
|
109
|
+
case 25:
|
|
130
110
|
case "end":
|
|
131
111
|
return _context.stop();
|
|
132
112
|
}
|
|
133
|
-
}, _callee, this, [[
|
|
113
|
+
}, _callee, this, [[4, 21]]);
|
|
134
114
|
}));
|
|
135
115
|
function gatherReachability() {
|
|
136
116
|
return _gatherReachability.apply(this, arguments);
|
|
@@ -148,7 +128,7 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
148
128
|
key: "getReachabilityMetrics",
|
|
149
129
|
value: (function () {
|
|
150
130
|
var _getReachabilityMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
151
|
-
var stats, updateStats, resultsJson,
|
|
131
|
+
var stats, updateStats, resultsJson, results;
|
|
152
132
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
153
133
|
while (1) switch (_context2.prev = _context2.next) {
|
|
154
134
|
case 0:
|
|
@@ -163,13 +143,12 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
163
143
|
reachability_vmn_tcp_failed: 0
|
|
164
144
|
};
|
|
165
145
|
updateStats = function updateStats(clusterType, result) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
var outcome = result.udp.reachable === 'true' ? 'success' : 'failed';
|
|
146
|
+
if (result.udp && result.udp.result !== 'untested') {
|
|
147
|
+
var outcome = result.udp.result === 'reachable' ? 'success' : 'failed';
|
|
169
148
|
stats["reachability_".concat(clusterType, "_udp_").concat(outcome)] += 1;
|
|
170
149
|
}
|
|
171
|
-
if (
|
|
172
|
-
var _outcome = result.tcp.
|
|
150
|
+
if (result.tcp && result.tcp.result !== 'untested') {
|
|
151
|
+
var _outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';
|
|
173
152
|
stats["reachability_".concat(clusterType, "_tcp_").concat(_outcome)] += 1;
|
|
174
153
|
}
|
|
175
154
|
};
|
|
@@ -178,8 +157,8 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
178
157
|
return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
|
|
179
158
|
case 5:
|
|
180
159
|
resultsJson = _context2.sent;
|
|
181
|
-
|
|
182
|
-
(0, _values.default)(
|
|
160
|
+
results = JSON.parse(resultsJson);
|
|
161
|
+
(0, _values.default)(results).forEach(function (result) {
|
|
183
162
|
updateStats(result.isVideoMesh ? 'vmn' : 'public', result);
|
|
184
163
|
});
|
|
185
164
|
_context2.next = 13;
|
|
@@ -202,45 +181,91 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
202
181
|
}
|
|
203
182
|
return getReachabilityMetrics;
|
|
204
183
|
}()
|
|
184
|
+
/**
|
|
185
|
+
* Maps our internal transport result to the format that backend expects
|
|
186
|
+
* @param {TransportResult} transportResult
|
|
187
|
+
* @returns {TransportResultForBackend}
|
|
188
|
+
*/
|
|
189
|
+
)
|
|
190
|
+
}, {
|
|
191
|
+
key: "mapTransportResultToBackendDataFormat",
|
|
192
|
+
value: function mapTransportResultToBackendDataFormat(transportResult) {
|
|
193
|
+
var output = {};
|
|
194
|
+
for (var _i = 0, _Object$entries = (0, _entries.default)(transportResult); _i < _Object$entries.length; _i++) {
|
|
195
|
+
var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
|
|
196
|
+
_key = _Object$entries$_i[0],
|
|
197
|
+
value = _Object$entries$_i[1];
|
|
198
|
+
switch (_key) {
|
|
199
|
+
case 'result':
|
|
200
|
+
switch (value) {
|
|
201
|
+
case 'reachable':
|
|
202
|
+
output.reachable = 'true';
|
|
203
|
+
break;
|
|
204
|
+
case 'unreachable':
|
|
205
|
+
output.reachable = 'false';
|
|
206
|
+
break;
|
|
207
|
+
case 'untested':
|
|
208
|
+
output.untested = 'true';
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
case 'latencyInMilliseconds':
|
|
213
|
+
output.latencyInMilliseconds = value.toString();
|
|
214
|
+
break;
|
|
215
|
+
default:
|
|
216
|
+
output[_key] = value;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return output;
|
|
220
|
+
}
|
|
221
|
+
|
|
205
222
|
/**
|
|
206
223
|
* Reachability results as an object in the format that backend expects
|
|
207
224
|
*
|
|
208
225
|
* @returns {any} reachability results that need to be sent to the backend
|
|
209
226
|
*/
|
|
210
|
-
)
|
|
211
227
|
}, {
|
|
212
228
|
key: "getReachabilityResults",
|
|
213
229
|
value: (function () {
|
|
214
230
|
var _getReachabilityResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
215
|
-
var
|
|
231
|
+
var _this = this;
|
|
232
|
+
var results, resultsJson, allClusterResults;
|
|
216
233
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
217
234
|
while (1) switch (_context3.prev = _context3.next) {
|
|
218
235
|
case 0:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
_context3.prev = 1;
|
|
222
|
-
_context3.next = 4;
|
|
236
|
+
_context3.prev = 0;
|
|
237
|
+
_context3.next = 3;
|
|
223
238
|
return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
|
|
224
|
-
case
|
|
239
|
+
case 3:
|
|
225
240
|
resultsJson = _context3.sent;
|
|
226
|
-
|
|
227
|
-
results = (0, _lodash.mapValues)(
|
|
228
|
-
return
|
|
241
|
+
allClusterResults = JSON.parse(resultsJson);
|
|
242
|
+
results = (0, _lodash.mapValues)(allClusterResults, function (clusterResult) {
|
|
243
|
+
return {
|
|
244
|
+
udp: _this.mapTransportResultToBackendDataFormat(clusterResult.udp || {
|
|
245
|
+
result: 'untested'
|
|
246
|
+
}),
|
|
247
|
+
tcp: _this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {
|
|
248
|
+
result: 'untested'
|
|
249
|
+
}),
|
|
250
|
+
xtls: _this.mapTransportResultToBackendDataFormat(clusterResult.xtls || {
|
|
251
|
+
result: 'untested'
|
|
252
|
+
})
|
|
253
|
+
};
|
|
229
254
|
});
|
|
230
|
-
_context3.next =
|
|
255
|
+
_context3.next = 11;
|
|
231
256
|
break;
|
|
232
|
-
case
|
|
233
|
-
_context3.prev =
|
|
234
|
-
_context3.t0 = _context3["catch"](
|
|
257
|
+
case 8:
|
|
258
|
+
_context3.prev = 8;
|
|
259
|
+
_context3.t0 = _context3["catch"](0);
|
|
235
260
|
// empty storage, that's ok
|
|
236
261
|
_loggerProxy.default.logger.warn('Roap:request#attachReachabilityData --> Error parsing reachability data: ', _context3.t0);
|
|
237
|
-
case
|
|
262
|
+
case 11:
|
|
238
263
|
return _context3.abrupt("return", results);
|
|
239
|
-
case
|
|
264
|
+
case 12:
|
|
240
265
|
case "end":
|
|
241
266
|
return _context3.stop();
|
|
242
267
|
}
|
|
243
|
-
}, _callee3, this, [[
|
|
268
|
+
}, _callee3, this, [[0, 8]]);
|
|
244
269
|
}));
|
|
245
270
|
function getReachabilityResults() {
|
|
246
271
|
return _getReachabilityResults.apply(this, arguments);
|
|
@@ -271,8 +296,8 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
271
296
|
try {
|
|
272
297
|
reachabilityResults = JSON.parse(reachabilityData);
|
|
273
298
|
reachable = (0, _values.default)(reachabilityResults).some(function (result) {
|
|
274
|
-
var _result$
|
|
275
|
-
return !result.isVideoMesh && (((_result$
|
|
299
|
+
var _result$udp, _result$tcp;
|
|
300
|
+
return !result.isVideoMesh && (((_result$udp = result.udp) === null || _result$udp === void 0 ? void 0 : _result$udp.result) === 'reachable' || ((_result$tcp = result.tcp) === null || _result$tcp === void 0 ? void 0 : _result$tcp.result) === 'reachable');
|
|
276
301
|
});
|
|
277
302
|
} catch (e) {
|
|
278
303
|
_loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
|
|
@@ -290,255 +315,36 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
290
315
|
}
|
|
291
316
|
return isAnyPublicClusterReachable;
|
|
292
317
|
}()
|
|
293
|
-
/**
|
|
294
|
-
* Generate peerConnection config settings
|
|
295
|
-
* @param {object} cluster
|
|
296
|
-
* @returns {object} peerConnectionConfig
|
|
297
|
-
* @private
|
|
298
|
-
* @memberof Reachability
|
|
299
|
-
*/
|
|
300
|
-
)
|
|
301
|
-
}, {
|
|
302
|
-
key: "buildPeerConnectionConfig",
|
|
303
|
-
value: function buildPeerConnectionConfig(cluster) {
|
|
304
|
-
var iceServers = (0, _lodash.uniq)(cluster.udp).map(function (url) {
|
|
305
|
-
return {
|
|
306
|
-
username: '',
|
|
307
|
-
credential: '',
|
|
308
|
-
urls: [url]
|
|
309
|
-
};
|
|
310
|
-
});
|
|
311
|
-
return {
|
|
312
|
-
iceServers: (0, _toConsumableArray2.default)(iceServers),
|
|
313
|
-
iceCandidatePoolSize: '0',
|
|
314
|
-
iceTransportPolicy: 'all'
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Creates an RTCPeerConnection
|
|
320
|
-
* @param {object} cluster
|
|
321
|
-
* @returns {RTCPeerConnection} peerConnection
|
|
322
|
-
* @private
|
|
323
|
-
* @memberof Reachability
|
|
324
|
-
*/
|
|
325
|
-
}, {
|
|
326
|
-
key: "createPeerConnection",
|
|
327
|
-
value: function createPeerConnection(cluster) {
|
|
328
|
-
var key = cluster.key,
|
|
329
|
-
config = cluster.config;
|
|
330
|
-
try {
|
|
331
|
-
var peerConnection = new window.RTCPeerConnection(config);
|
|
332
|
-
|
|
333
|
-
// @ts-ignore
|
|
334
|
-
peerConnection.key = key;
|
|
335
|
-
return peerConnection;
|
|
336
|
-
} catch (peerConnectionError) {
|
|
337
|
-
_loggerProxy.default.logger.log("Reachability:index#createPeerConnection --> Error creating peerConnection: ".concat(peerConnectionError));
|
|
338
|
-
return null;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Gets total elapsed time
|
|
344
|
-
* @param {RTCPeerConnection} peerConnection
|
|
345
|
-
* @returns {Number} Milliseconds
|
|
346
|
-
* @private
|
|
347
|
-
* @memberof Reachability
|
|
348
|
-
*/
|
|
349
|
-
}, {
|
|
350
|
-
key: "getElapsedTime",
|
|
351
|
-
value: function getElapsedTime(peerConnection) {
|
|
352
|
-
var startTime = peerConnection.begin;
|
|
353
|
-
delete peerConnection.begin;
|
|
354
|
-
return (0, _now.default)() - startTime;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* creates offer and generates localSDP
|
|
359
|
-
* @param {object} clusterList cluster List
|
|
360
|
-
* @returns {Promise} Reachability latency results
|
|
361
|
-
* @private
|
|
362
|
-
* @memberof Reachability
|
|
363
|
-
*/
|
|
364
|
-
}, {
|
|
365
|
-
key: "getLocalSDPForClusters",
|
|
366
|
-
value: function getLocalSDPForClusters(clusterList) {
|
|
367
|
-
var _this = this;
|
|
368
|
-
var clusters = (0, _toConsumableArray2.default)((0, _keys.default)(clusterList));
|
|
369
|
-
clusters = clusters.map( /*#__PURE__*/function () {
|
|
370
|
-
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(key) {
|
|
371
|
-
var cluster, config, peerConnection, description;
|
|
372
|
-
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
373
|
-
while (1) switch (_context5.prev = _context5.next) {
|
|
374
|
-
case 0:
|
|
375
|
-
cluster = clusterList[key];
|
|
376
|
-
config = _this.buildPeerConnectionConfig(cluster);
|
|
377
|
-
peerConnection = _this.createPeerConnection({
|
|
378
|
-
key: key,
|
|
379
|
-
config: config
|
|
380
|
-
});
|
|
381
|
-
_context5.next = 5;
|
|
382
|
-
return peerConnection.createOffer({
|
|
383
|
-
offerToReceiveAudio: true
|
|
384
|
-
});
|
|
385
|
-
case 5:
|
|
386
|
-
description = _context5.sent;
|
|
387
|
-
// @ts-ignore
|
|
388
|
-
peerConnection.begin = (0, _now.default)();
|
|
389
|
-
peerConnection.setLocalDescription(description);
|
|
390
|
-
return _context5.abrupt("return", _this.iceGatheringState(peerConnection, cluster.isVideoMesh).catch(function (iceGatheringStateError) {
|
|
391
|
-
_loggerProxy.default.logger.log("Reachability:index#getLocalSDPForClusters --> Error in getLocalSDP : ".concat(iceGatheringStateError));
|
|
392
|
-
}));
|
|
393
|
-
case 9:
|
|
394
|
-
case "end":
|
|
395
|
-
return _context5.stop();
|
|
396
|
-
}
|
|
397
|
-
}, _callee5);
|
|
398
|
-
}));
|
|
399
|
-
return function (_x) {
|
|
400
|
-
return _ref.apply(this, arguments);
|
|
401
|
-
};
|
|
402
|
-
}());
|
|
403
|
-
return _promise.default.all(clusters).then(this.parseIceResultsToInternalReachabilityResults).then(function (reachabilityLatencyResults) {
|
|
404
|
-
_this.logUnreachableClusters();
|
|
405
|
-
|
|
406
|
-
// return results
|
|
407
|
-
return reachabilityLatencyResults;
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
|
|
411
318
|
/**
|
|
412
319
|
* Get list of all unreachable clusters
|
|
413
320
|
* @returns {array} Unreachable clusters
|
|
414
321
|
* @private
|
|
415
322
|
* @memberof Reachability
|
|
416
323
|
*/
|
|
324
|
+
)
|
|
417
325
|
}, {
|
|
418
|
-
key: "
|
|
419
|
-
value: function
|
|
326
|
+
key: "getUnreachableClusters",
|
|
327
|
+
value: function getUnreachableClusters() {
|
|
420
328
|
var unreachableList = [];
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
/**
|
|
432
|
-
* Attach an event handler for the icegatheringstatechange
|
|
433
|
-
* event and measure latency.
|
|
434
|
-
* @param {RTCPeerConnection} peerConnection
|
|
435
|
-
* @returns {undefined}
|
|
436
|
-
* @private
|
|
437
|
-
* @memberof Reachability
|
|
438
|
-
*/
|
|
439
|
-
}, {
|
|
440
|
-
key: "handleIceGatheringStateChange",
|
|
441
|
-
value: function handleIceGatheringStateChange(peerConnection) {
|
|
442
|
-
var _this2 = this;
|
|
443
|
-
peerConnection.onicegatheringstatechange = function () {
|
|
444
|
-
var COMPLETE = _constants.ICE_GATHERING_STATE.COMPLETE;
|
|
445
|
-
if (peerConnection.iceConnectionState === COMPLETE) {
|
|
446
|
-
var elapsed = _this2.getElapsedTime(peerConnection);
|
|
447
|
-
|
|
448
|
-
// @ts-ignore
|
|
449
|
-
_loggerProxy.default.logger.log( // @ts-ignore
|
|
450
|
-
"Reachability:index#onIceGatheringStateChange --> Successfully pinged ".concat(peerConnection.key, ":"), elapsed);
|
|
451
|
-
_this2.setLatencyAndClose(peerConnection, elapsed);
|
|
329
|
+
(0, _entries.default)(this.clusterReachability).forEach(function (_ref) {
|
|
330
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
331
|
+
key = _ref2[0],
|
|
332
|
+
clusterReachability = _ref2[1];
|
|
333
|
+
var result = clusterReachability.getResult();
|
|
334
|
+
if (result.udp.result === 'unreachable') {
|
|
335
|
+
unreachableList.push({
|
|
336
|
+
name: key,
|
|
337
|
+
protocol: 'udp'
|
|
338
|
+
});
|
|
452
339
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
* event and measure latency.
|
|
459
|
-
* @param {RTCPeerConnection} peerConnection
|
|
460
|
-
* @returns {undefined}
|
|
461
|
-
* @private
|
|
462
|
-
* @memberof Reachability
|
|
463
|
-
*/
|
|
464
|
-
}, {
|
|
465
|
-
key: "handleOnIceCandidate",
|
|
466
|
-
value: function handleOnIceCandidate(peerConnection) {
|
|
467
|
-
var _this3 = this;
|
|
468
|
-
peerConnection.onicecandidate = function (e) {
|
|
469
|
-
var SERVER_REFLEXIVE = 'srflx';
|
|
470
|
-
if (e.candidate && String(e.candidate.type).toLowerCase() === SERVER_REFLEXIVE) {
|
|
471
|
-
var elapsed = _this3.getElapsedTime(peerConnection);
|
|
472
|
-
_loggerProxy.default.logger.log( // @ts-ignore
|
|
473
|
-
"Reachability:index#onIceCandidate --> Successfully pinged ".concat(peerConnection.key, ":"), elapsed);
|
|
474
|
-
// order is important
|
|
475
|
-
_this3.addPublicIP(peerConnection, e.candidate.address);
|
|
476
|
-
_this3.setLatencyAndClose(peerConnection, elapsed);
|
|
340
|
+
if (result.tcp.result === 'unreachable') {
|
|
341
|
+
unreachableList.push({
|
|
342
|
+
name: key,
|
|
343
|
+
protocol: 'tcp'
|
|
344
|
+
});
|
|
477
345
|
}
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* An event handler on an RTCPeerConnection when the state of the ICE
|
|
483
|
-
* candidate gathering process changes. Used to measure connection
|
|
484
|
-
* speed.
|
|
485
|
-
* @private
|
|
486
|
-
* @param {RTCPeerConnection} peerConnection
|
|
487
|
-
* @param {boolean} isVideoMesh
|
|
488
|
-
* @returns {Promise}
|
|
489
|
-
*/
|
|
490
|
-
}, {
|
|
491
|
-
key: "iceGatheringState",
|
|
492
|
-
value: function iceGatheringState(peerConnection, isVideoMesh) {
|
|
493
|
-
var _this4 = this;
|
|
494
|
-
var ELAPSED = 'elapsed';
|
|
495
|
-
var timeout = isVideoMesh ? VIDEO_MESH_TIMEOUT : DEFAULT_TIMEOUT;
|
|
496
|
-
return new _promise.default(function (resolve) {
|
|
497
|
-
var peerConnectionProxy = new window.Proxy(peerConnection, {
|
|
498
|
-
// eslint-disable-next-line require-jsdoc
|
|
499
|
-
get: function get(target, property) {
|
|
500
|
-
var targetMember = target[property];
|
|
501
|
-
if (typeof targetMember === 'function') {
|
|
502
|
-
return targetMember.bind(target);
|
|
503
|
-
}
|
|
504
|
-
return targetMember;
|
|
505
|
-
},
|
|
506
|
-
set: function set(target, property, value) {
|
|
507
|
-
// only intercept elapsed property
|
|
508
|
-
if (property === ELAPSED) {
|
|
509
|
-
resolve({
|
|
510
|
-
// @ts-ignore
|
|
511
|
-
clusterId: peerConnection.key,
|
|
512
|
-
isVideoMesh: isVideoMesh,
|
|
513
|
-
// @ts-ignore
|
|
514
|
-
publicIPs: target.publicIPs,
|
|
515
|
-
elapsed: value
|
|
516
|
-
});
|
|
517
|
-
return true;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
// pass thru
|
|
521
|
-
return window.Reflect.set(target, property, value);
|
|
522
|
-
}
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
// Using peerConnection proxy so handle functions below
|
|
526
|
-
// won't be coupled to our promise implementation
|
|
527
|
-
_this4.handleIceGatheringStateChange(peerConnectionProxy);
|
|
528
|
-
_this4.handleOnIceCandidate(peerConnectionProxy);
|
|
529
|
-
|
|
530
|
-
// Set maximum timeout
|
|
531
|
-
window.setTimeout(function () {
|
|
532
|
-
var CLOSED = _constants.CONNECTION_STATE.CLOSED;
|
|
533
|
-
|
|
534
|
-
// Close any open peerConnections
|
|
535
|
-
if (peerConnectionProxy.connectionState !== CLOSED) {
|
|
536
|
-
// order is important
|
|
537
|
-
_this4.addPublicIP(peerConnectionProxy, null);
|
|
538
|
-
_this4.setLatencyAndClose(peerConnectionProxy, null);
|
|
539
|
-
}
|
|
540
|
-
}, timeout);
|
|
541
346
|
});
|
|
347
|
+
return unreachableList;
|
|
542
348
|
}
|
|
543
349
|
|
|
544
350
|
/**
|
|
@@ -550,157 +356,65 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
550
356
|
}, {
|
|
551
357
|
key: "logUnreachableClusters",
|
|
552
358
|
value: function logUnreachableClusters() {
|
|
553
|
-
var list = this.
|
|
554
|
-
list.forEach(function (
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Calculates time to establish connection
|
|
561
|
-
* @param {Array<ICECandidateResult>} iceResults iceResults
|
|
562
|
-
* @returns {object} reachabilityMap
|
|
563
|
-
* @protected
|
|
564
|
-
* @memberof Reachability
|
|
565
|
-
*/
|
|
566
|
-
}, {
|
|
567
|
-
key: "parseIceResultsToInternalReachabilityResults",
|
|
568
|
-
value: function parseIceResultsToInternalReachabilityResults(iceResults) {
|
|
569
|
-
var reachabilityMap = {};
|
|
570
|
-
iceResults.forEach(function (_ref2) {
|
|
571
|
-
var clusterId = _ref2.clusterId,
|
|
572
|
-
isVideoMesh = _ref2.isVideoMesh,
|
|
573
|
-
elapsed = _ref2.elapsed,
|
|
574
|
-
publicIPs = _ref2.publicIPs;
|
|
575
|
-
var latencyResult = {};
|
|
576
|
-
if (!elapsed) {
|
|
577
|
-
(0, _assign.default)(latencyResult, {
|
|
578
|
-
reachable: 'false'
|
|
579
|
-
});
|
|
580
|
-
} else {
|
|
581
|
-
(0, _assign.default)(latencyResult, {
|
|
582
|
-
reachable: 'true',
|
|
583
|
-
latencyInMilliseconds: elapsed.toString()
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
if (publicIPs) {
|
|
587
|
-
(0, _assign.default)(latencyResult, {
|
|
588
|
-
clientMediaIPs: publicIPs
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
reachabilityMap[clusterId] = {
|
|
592
|
-
udp: latencyResult,
|
|
593
|
-
tcp: {
|
|
594
|
-
untested: 'true'
|
|
595
|
-
},
|
|
596
|
-
xtls: {
|
|
597
|
-
untested: 'true'
|
|
598
|
-
},
|
|
599
|
-
isVideoMesh: isVideoMesh
|
|
600
|
-
};
|
|
359
|
+
var list = this.getUnreachableClusters();
|
|
360
|
+
list.forEach(function (_ref3) {
|
|
361
|
+
var name = _ref3.name,
|
|
362
|
+
protocol = _ref3.protocol;
|
|
363
|
+
_loggerProxy.default.logger.log("Reachability:index#logUnreachableClusters --> failed to reach ".concat(name, " over ").concat(protocol));
|
|
601
364
|
});
|
|
602
|
-
return reachabilityMap;
|
|
603
365
|
}
|
|
604
366
|
|
|
605
367
|
/**
|
|
606
|
-
*
|
|
607
|
-
* @param {
|
|
608
|
-
* @returns {Promise<
|
|
609
|
-
* @private
|
|
610
|
-
* @memberof Reachability
|
|
368
|
+
* Performs reachability checks for all clusters
|
|
369
|
+
* @param {ClusterList} clusterList
|
|
370
|
+
* @returns {Promise<ReachabilityResults>} reachability check results
|
|
611
371
|
*/
|
|
612
372
|
}, {
|
|
613
|
-
key: "
|
|
614
|
-
value: function
|
|
615
|
-
var
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
373
|
+
key: "performReachabilityChecks",
|
|
374
|
+
value: (function () {
|
|
375
|
+
var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(clusterList) {
|
|
376
|
+
var _this2 = this;
|
|
377
|
+
var results, includeTcpReachability, clusterReachabilityChecks;
|
|
378
|
+
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
379
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
380
|
+
case 0:
|
|
381
|
+
results = {};
|
|
382
|
+
if (!(!clusterList || !(0, _keys.default)(clusterList).length)) {
|
|
383
|
+
_context5.next = 3;
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
return _context5.abrupt("return", _promise.default.resolve(results));
|
|
387
|
+
case 3:
|
|
388
|
+
// @ts-ignore
|
|
389
|
+
includeTcpReachability = this.webex.config.meetings.experimental.enableTcpReachability;
|
|
390
|
+
_loggerProxy.default.logger.log("Reachability:index#performReachabilityChecks --> doing UDP".concat(includeTcpReachability ? ' and TCP' : '', " reachability checks"));
|
|
391
|
+
clusterReachabilityChecks = (0, _keys.default)(clusterList).map(function (key) {
|
|
392
|
+
var cluster = clusterList[key];
|
|
393
|
+
if (!includeTcpReachability) {
|
|
394
|
+
cluster.tcp = [];
|
|
395
|
+
}
|
|
396
|
+
_this2.clusterReachability[key] = new _clusterReachability.ClusterReachability(key, cluster);
|
|
397
|
+
return _this2.clusterReachability[key].start().then(function (result) {
|
|
398
|
+
results[key] = result;
|
|
399
|
+
results[key].isVideoMesh = cluster.isVideoMesh;
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
_context5.next = 8;
|
|
403
|
+
return _promise.default.all(clusterReachabilityChecks);
|
|
404
|
+
case 8:
|
|
405
|
+
this.logUnreachableClusters();
|
|
406
|
+
return _context5.abrupt("return", results);
|
|
407
|
+
case 10:
|
|
408
|
+
case "end":
|
|
409
|
+
return _context5.stop();
|
|
627
410
|
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Adds public IP (client media IPs)
|
|
637
|
-
* @param {RTCPeerConnection} peerConnection
|
|
638
|
-
* @param {string} publicIP
|
|
639
|
-
* @returns {void}
|
|
640
|
-
*/
|
|
641
|
-
}, {
|
|
642
|
-
key: "addPublicIP",
|
|
643
|
-
value: function addPublicIP(peerConnection, publicIP) {
|
|
644
|
-
var modifiedPeerConnection = peerConnection;
|
|
645
|
-
var CLOSED = _constants.CONNECTION_STATE.CLOSED;
|
|
646
|
-
if (modifiedPeerConnection.connectionState === CLOSED) {
|
|
647
|
-
_loggerProxy.default.logger.log("Reachability:index#addPublicIP --> Attempting to set publicIP of ".concat(publicIP, " on closed peerConnection."));
|
|
648
|
-
}
|
|
649
|
-
if (publicIP) {
|
|
650
|
-
if (modifiedPeerConnection.publicIPs) {
|
|
651
|
-
modifiedPeerConnection.publicIPs.push(publicIP);
|
|
652
|
-
} else {
|
|
653
|
-
modifiedPeerConnection.publicIPs = [publicIP];
|
|
654
|
-
}
|
|
655
|
-
} else {
|
|
656
|
-
modifiedPeerConnection.publicIPs = null;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Records latency and closes the peerConnection
|
|
662
|
-
* @param {RTCPeerConnection} peerConnection
|
|
663
|
-
* @param {number} elapsed Latency in milliseconds
|
|
664
|
-
* @returns {undefined}
|
|
665
|
-
* @private
|
|
666
|
-
* @memberof Reachability
|
|
667
|
-
*/
|
|
668
|
-
}, {
|
|
669
|
-
key: "setLatencyAndClose",
|
|
670
|
-
value: function setLatencyAndClose(peerConnection, elapsed) {
|
|
671
|
-
var REACHABLE = 'reachable';
|
|
672
|
-
var UNREACHABLE = 'unreachable';
|
|
673
|
-
var CLOSED = _constants.CONNECTION_STATE.CLOSED;
|
|
674
|
-
// @ts-ignore
|
|
675
|
-
var key = peerConnection.key;
|
|
676
|
-
var resultKey = elapsed === null ? UNREACHABLE : REACHABLE;
|
|
677
|
-
var intialState = (0, _defineProperty2.default)((0, _defineProperty2.default)({}, REACHABLE, 0), UNREACHABLE, 0);
|
|
678
|
-
if (peerConnection.connectionState === CLOSED) {
|
|
679
|
-
_loggerProxy.default.logger.log("Reachability:index#setLatencyAndClose --> Attempting to set latency of ".concat(elapsed, " on closed peerConnection."));
|
|
680
|
-
return;
|
|
411
|
+
}, _callee5, this);
|
|
412
|
+
}));
|
|
413
|
+
function performReachabilityChecks(_x) {
|
|
414
|
+
return _performReachabilityChecks.apply(this, arguments);
|
|
681
415
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
// Set to null in case this fired from
|
|
686
|
-
// an event other than onIceCandidate
|
|
687
|
-
peerConnection.onicecandidate = null;
|
|
688
|
-
peerConnection.close();
|
|
689
|
-
// @ts-ignore
|
|
690
|
-
peerConnection.elapsed = elapsed;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* utility function
|
|
695
|
-
* @returns {undefined}
|
|
696
|
-
* @private
|
|
697
|
-
* @memberof Reachability
|
|
698
|
-
*/
|
|
699
|
-
}, {
|
|
700
|
-
key: "setup",
|
|
701
|
-
value: function setup() {
|
|
702
|
-
this.clusterLatencyResults = {};
|
|
703
|
-
}
|
|
416
|
+
return performReachabilityChecks;
|
|
417
|
+
}())
|
|
704
418
|
}]);
|
|
705
419
|
return Reachability;
|
|
706
420
|
}();
|