@webex/plugin-meetings 3.3.0 → 3.3.1-next.10
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/constants.js +4 -2
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/mediaQualityMetrics/config.js +20 -16
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/index.js +30 -13
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +6 -1
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/index.js +82 -9
- package/dist/reachability/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +77 -27
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +46 -7
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/constants.d.ts +2 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +14 -2
- package/dist/types/meeting/index.d.ts +8 -0
- package/dist/types/reachability/index.d.ts +11 -0
- package/dist/types/statsAnalyzer/index.d.ts +14 -6
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +17 -4
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/constants.ts +2 -1
- package/src/mediaQualityMetrics/config.ts +22 -10
- package/src/meeting/index.ts +29 -14
- package/src/meetings/index.ts +7 -2
- package/src/reachability/index.ts +57 -0
- package/src/statsAnalyzer/index.ts +82 -22
- package/src/statsAnalyzer/mqaUtil.ts +68 -4
- package/test/unit/spec/meeting/index.js +28 -8
- package/test/unit/spec/meetings/index.js +38 -15
- package/test/unit/spec/reachability/index.ts +266 -0
- package/test/unit/spec/stats-analyzer/index.js +630 -314
|
@@ -317,6 +317,79 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
317
317
|
}
|
|
318
318
|
return isAnyPublicClusterReachable;
|
|
319
319
|
}()
|
|
320
|
+
/**
|
|
321
|
+
* Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none
|
|
322
|
+
* of the media clusters where reachable with any of the protocols. This is done
|
|
323
|
+
* irrespective of the config, so for example:
|
|
324
|
+
* if config.meetings.experimental.enableTlsReachability === false,
|
|
325
|
+
* it will return false, because TLS reachability won't be tested,
|
|
326
|
+
* so we can't say for sure that media backend is unreachable over TLS.
|
|
327
|
+
*
|
|
328
|
+
* @returns {boolean}
|
|
329
|
+
*/
|
|
330
|
+
)
|
|
331
|
+
}, {
|
|
332
|
+
key: "isWebexMediaBackendUnreachable",
|
|
333
|
+
value: (function () {
|
|
334
|
+
var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
335
|
+
var unreachable, reachabilityData, reachabilityResults, protocols;
|
|
336
|
+
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
337
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
338
|
+
case 0:
|
|
339
|
+
unreachable = false; // @ts-ignore
|
|
340
|
+
_context5.next = 3;
|
|
341
|
+
return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
|
|
342
|
+
case 3:
|
|
343
|
+
reachabilityData = _context5.sent;
|
|
344
|
+
if (reachabilityData) {
|
|
345
|
+
try {
|
|
346
|
+
reachabilityResults = JSON.parse(reachabilityData);
|
|
347
|
+
protocols = {
|
|
348
|
+
udp: {
|
|
349
|
+
tested: false,
|
|
350
|
+
reachable: undefined
|
|
351
|
+
},
|
|
352
|
+
tcp: {
|
|
353
|
+
tested: false,
|
|
354
|
+
reachable: undefined
|
|
355
|
+
},
|
|
356
|
+
xtls: {
|
|
357
|
+
tested: false,
|
|
358
|
+
reachable: undefined
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
(0, _values.default)(reachabilityResults).forEach(function (result) {
|
|
362
|
+
(0, _keys.default)(protocols).forEach(function (protocol) {
|
|
363
|
+
var _result$protocol, _result$protocol2;
|
|
364
|
+
if (((_result$protocol = result[protocol]) === null || _result$protocol === void 0 ? void 0 : _result$protocol.result) === 'reachable' || ((_result$protocol2 = result[protocol]) === null || _result$protocol2 === void 0 ? void 0 : _result$protocol2.result) === 'unreachable') {
|
|
365
|
+
protocols[protocol].tested = true;
|
|
366
|
+
|
|
367
|
+
// we need at least 1 'reachable' result to mark the whole protocol as reachable
|
|
368
|
+
if (result[protocol].result === 'reachable') {
|
|
369
|
+
protocols[protocol].reachable = true;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
unreachable = (0, _values.default)(protocols).every(function (protocol) {
|
|
375
|
+
return protocol.tested && !protocol.reachable;
|
|
376
|
+
});
|
|
377
|
+
} catch (e) {
|
|
378
|
+
_loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return _context5.abrupt("return", unreachable);
|
|
382
|
+
case 6:
|
|
383
|
+
case "end":
|
|
384
|
+
return _context5.stop();
|
|
385
|
+
}
|
|
386
|
+
}, _callee5, this);
|
|
387
|
+
}));
|
|
388
|
+
function isWebexMediaBackendUnreachable() {
|
|
389
|
+
return _isWebexMediaBackendUnreachable.apply(this, arguments);
|
|
390
|
+
}
|
|
391
|
+
return isWebexMediaBackendUnreachable;
|
|
392
|
+
}()
|
|
320
393
|
/**
|
|
321
394
|
* Get list of all unreachable clusters
|
|
322
395
|
* @returns {array} Unreachable clusters
|
|
@@ -380,18 +453,18 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
380
453
|
}, {
|
|
381
454
|
key: "performReachabilityChecks",
|
|
382
455
|
value: (function () {
|
|
383
|
-
var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
456
|
+
var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(clusterList) {
|
|
384
457
|
var _this2 = this;
|
|
385
458
|
var results, clusterReachabilityChecks;
|
|
386
|
-
return _regenerator.default.wrap(function
|
|
387
|
-
while (1) switch (
|
|
459
|
+
return _regenerator.default.wrap(function _callee6$(_context6) {
|
|
460
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
388
461
|
case 0:
|
|
389
462
|
results = {};
|
|
390
463
|
if (!(!clusterList || !(0, _keys.default)(clusterList).length)) {
|
|
391
|
-
|
|
464
|
+
_context6.next = 3;
|
|
392
465
|
break;
|
|
393
466
|
}
|
|
394
|
-
return
|
|
467
|
+
return _context6.abrupt("return", _promise.default.resolve(results));
|
|
395
468
|
case 3:
|
|
396
469
|
_loggerProxy.default.logger.log("Reachability:index#performReachabilityChecks --> doing UDP".concat(
|
|
397
470
|
// @ts-ignore
|
|
@@ -420,16 +493,16 @@ var Reachability = exports.default = /*#__PURE__*/function () {
|
|
|
420
493
|
results[key].isVideoMesh = cluster.isVideoMesh;
|
|
421
494
|
});
|
|
422
495
|
});
|
|
423
|
-
|
|
496
|
+
_context6.next = 7;
|
|
424
497
|
return _promise.default.all(clusterReachabilityChecks);
|
|
425
498
|
case 7:
|
|
426
499
|
this.logUnreachableClusters();
|
|
427
|
-
return
|
|
500
|
+
return _context6.abrupt("return", results);
|
|
428
501
|
case 9:
|
|
429
502
|
case "end":
|
|
430
|
-
return
|
|
503
|
+
return _context6.stop();
|
|
431
504
|
}
|
|
432
|
-
},
|
|
505
|
+
}, _callee6, this);
|
|
433
506
|
}));
|
|
434
507
|
function performReachabilityChecks(_x) {
|
|
435
508
|
return _performReachabilityChecks.apply(this, arguments);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","Reachability","exports","default","webex","_classCallCheck2","_defineProperty2","REACHABILITY","namespace","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","results","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","performReachabilityChecks","boundedStorage","put","localStorageResult","_stringify","localStorageJoinCookie","LoggerProxy","logger","log","abrupt","t0","error","stop","gatherReachability","apply","arguments","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","_callee2$","_context2","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","result","udp","outcome","concat","tcp","xtls","get","JSON","parse","_values","forEach","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","length","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","e","isAnyPublicClusterReachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","push","name","protocol","logUnreachableClusters","list","_ref3","_performReachabilityChecks","_callee5","clusterList","_this2","clusterReachabilityChecks","_callee5$","_context5","_keys","_promise","resolve","config","meetings","experimental","enableTcpReachability","enableTlsReachability","map","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","start","then","all","_x"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {mapValues} from 'lodash';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClusterReachability,\n ClusterReachabilityResult,\n TransportResult,\n} from './clusterReachability';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n // Perform Reachability Check\n const results = await this.performReachabilityChecks(clusters);\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n LoggerProxy.logger.log(\n 'Reachability:index#gatherReachability --> Reachability checks completed'\n );\n\n return results;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<ReachabilityResults>} reachability check results\n */\n private async performReachabilityChecks(clusterList: ClusterList): Promise<ReachabilityResults> {\n const results: ReachabilityResults = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return Promise.resolve(results);\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n const clusterReachabilityChecks = Object.keys(clusterList).map((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n\n return this.clusterReachability[key].start().then((result) => {\n results[key] = result;\n results[key].isVideoMesh = cluster.isVideoMesh;\n });\n });\n\n await Promise.all(clusterReachabilityChecks);\n\n this.logUnreachableClusters();\n\n return results;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_lodash","require","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","Reachability","exports","default","webex","_classCallCheck2","_defineProperty2","REACHABILITY","namespace","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","results","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","performReachabilityChecks","boundedStorage","put","localStorageResult","_stringify","localStorageJoinCookie","LoggerProxy","logger","log","abrupt","t0","error","stop","gatherReachability","apply","arguments","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","_callee2$","_context2","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","result","udp","outcome","concat","tcp","xtls","get","JSON","parse","_values","forEach","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","length","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","e","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee5","unreachable","protocols","_callee5$","_context5","tested","undefined","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","push","name","logUnreachableClusters","list","_ref3","_performReachabilityChecks","_callee6","clusterList","_this2","clusterReachabilityChecks","_callee6$","_context6","_promise","resolve","config","meetings","experimental","enableTcpReachability","enableTlsReachability","map","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","start","then","all","_x"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {mapValues} from 'lodash';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClusterReachability,\n ClusterReachabilityResult,\n TransportResult,\n} from './clusterReachability';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n // Perform Reachability Check\n const results = await this.performReachabilityChecks(clusters);\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n LoggerProxy.logger.log(\n 'Reachability:index#gatherReachability --> Reachability checks completed'\n );\n\n return results;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none\n * of the media clusters where reachable with any of the protocols. This is done\n * irrespective of the config, so for example:\n * if config.meetings.experimental.enableTlsReachability === false,\n * it will return false, because TLS reachability won't be tested,\n * so we can't say for sure that media backend is unreachable over TLS.\n *\n * @returns {boolean}\n */\n async isWebexMediaBackendUnreachable() {\n let unreachable = false;\n\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n const protocols = {\n udp: {tested: false, reachable: undefined},\n tcp: {tested: false, reachable: undefined},\n xtls: {tested: false, reachable: undefined},\n };\n\n Object.values(reachabilityResults).forEach((result) => {\n Object.keys(protocols).forEach((protocol) => {\n if (\n result[protocol]?.result === 'reachable' ||\n result[protocol]?.result === 'unreachable'\n ) {\n protocols[protocol].tested = true;\n\n // we need at least 1 'reachable' result to mark the whole protocol as reachable\n if (result[protocol].result === 'reachable') {\n protocols[protocol].reachable = true;\n }\n }\n });\n });\n\n unreachable = Object.values(protocols).every(\n (protocol) => protocol.tested && !protocol.reachable\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return unreachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<ReachabilityResults>} reachability check results\n */\n private async performReachabilityChecks(clusterList: ClusterList): Promise<ReachabilityResults> {\n const results: ReachabilityResults = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return Promise.resolve(results);\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n const clusterReachabilityChecks = Object.keys(clusterList).map((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n\n return this.clusterReachability[key].start().then((result) => {\n results[key] = result;\n results[key].isVideoMesh = cluster.isVideoMesh;\n });\n });\n\n await Promise.all(clusterReachabilityChecks);\n\n this.logUnreachableClusters();\n\n return results;\n }\n}\n"],"mappings":"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"}
|
|
@@ -69,18 +69,25 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
69
69
|
* Creates a new instance of StatsAnalyzer
|
|
70
70
|
* @constructor
|
|
71
71
|
* @public
|
|
72
|
-
* @param {Object} config SDK Configuration Object
|
|
73
|
-
* @param {Function} receiveSlotCallback Callback used to access receive slots.
|
|
74
|
-
* @param {Object} networkQualityMonitor
|
|
75
|
-
* @param {Object} statsResults Default properties for stats
|
|
72
|
+
* @param {Object} config - SDK Configuration Object
|
|
73
|
+
* @param {Function} receiveSlotCallback - Callback used to access receive slots.
|
|
74
|
+
* @param {Object} networkQualityMonitor - Class for assessing network characteristics (jitter, packetLoss, latency)
|
|
75
|
+
* @param {Object} statsResults - Default properties for stats
|
|
76
|
+
* @param {boolean | undefined} isMultistream - Param indicating if the media connection is multistream or not
|
|
76
77
|
*/
|
|
77
|
-
function StatsAnalyzer(
|
|
78
|
+
function StatsAnalyzer(_ref) {
|
|
78
79
|
var _this;
|
|
79
|
-
var
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
var config = _ref.config,
|
|
81
|
+
_ref$receiveSlotCallb = _ref.receiveSlotCallback,
|
|
82
|
+
receiveSlotCallback = _ref$receiveSlotCallb === void 0 ? function () {
|
|
83
|
+
return undefined;
|
|
84
|
+
} : _ref$receiveSlotCallb,
|
|
85
|
+
_ref$networkQualityMo = _ref.networkQualityMonitor,
|
|
86
|
+
networkQualityMonitor = _ref$networkQualityMo === void 0 ? {} : _ref$networkQualityMo,
|
|
87
|
+
_ref$statsResults = _ref.statsResults,
|
|
88
|
+
statsResults = _ref$statsResults === void 0 ? _global.default : _ref$statsResults,
|
|
89
|
+
_ref$isMultistream = _ref.isMultistream,
|
|
90
|
+
isMultistream = _ref$isMultistream === void 0 ? false : _ref$isMultistream;
|
|
84
91
|
(0, _classCallCheck2.default)(this, StatsAnalyzer);
|
|
85
92
|
_this = _super.call(this);
|
|
86
93
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "config", void 0);
|
|
@@ -100,6 +107,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
100
107
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "localIpAddress", void 0);
|
|
101
108
|
// Returns the local IP address for diagnostics. this is the local IP of the interface used for the current media connection a host can have many local Ip Addresses
|
|
102
109
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "receiveSlotCallback", void 0);
|
|
110
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isMultistream", void 0);
|
|
103
111
|
/**
|
|
104
112
|
* emits started/stopped events for local/remote media by checking
|
|
105
113
|
* if given values are increasing or not. The previousValue, currentValue
|
|
@@ -251,6 +259,7 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
251
259
|
_this.receiveSlotCallback = receiveSlotCallback;
|
|
252
260
|
_this.successfulCandidatePair = {};
|
|
253
261
|
_this.localIpAddress = '';
|
|
262
|
+
_this.isMultistream = isMultistream;
|
|
254
263
|
return _this;
|
|
255
264
|
}
|
|
256
265
|
|
|
@@ -333,56 +342,64 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
333
342
|
audioSender: audioSender,
|
|
334
343
|
statsResults: this.statsResults,
|
|
335
344
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
336
|
-
baseMediaType: 'audio-send'
|
|
345
|
+
baseMediaType: 'audio-send',
|
|
346
|
+
isMultistream: this.isMultistream
|
|
337
347
|
});
|
|
338
348
|
newMqa.audioTransmit.push(audioSender);
|
|
339
349
|
(0, _mqaUtil.getAudioSenderMqa)({
|
|
340
350
|
audioSender: audioShareSender,
|
|
341
351
|
statsResults: this.statsResults,
|
|
342
352
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
343
|
-
baseMediaType: 'audio-share-send'
|
|
353
|
+
baseMediaType: 'audio-share-send',
|
|
354
|
+
isMultistream: this.isMultistream
|
|
344
355
|
});
|
|
345
356
|
newMqa.audioTransmit.push(audioShareSender);
|
|
346
357
|
(0, _mqaUtil.getAudioReceiverMqa)({
|
|
347
358
|
audioReceiver: audioReceiver,
|
|
348
359
|
statsResults: this.statsResults,
|
|
349
360
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
350
|
-
baseMediaType: 'audio-recv'
|
|
361
|
+
baseMediaType: 'audio-recv',
|
|
362
|
+
isMultistream: this.isMultistream
|
|
351
363
|
});
|
|
352
364
|
newMqa.audioReceive.push(audioReceiver);
|
|
353
365
|
(0, _mqaUtil.getAudioReceiverMqa)({
|
|
354
366
|
audioReceiver: audioShareReceiver,
|
|
355
367
|
statsResults: this.statsResults,
|
|
356
368
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
357
|
-
baseMediaType: 'audio-share-recv'
|
|
369
|
+
baseMediaType: 'audio-share-recv',
|
|
370
|
+
isMultistream: this.isMultistream
|
|
358
371
|
});
|
|
359
372
|
newMqa.audioReceive.push(audioShareReceiver);
|
|
360
373
|
(0, _mqaUtil.getVideoSenderMqa)({
|
|
361
374
|
videoSender: videoSender,
|
|
362
375
|
statsResults: this.statsResults,
|
|
363
376
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
364
|
-
baseMediaType: 'video-send'
|
|
377
|
+
baseMediaType: 'video-send',
|
|
378
|
+
isMultistream: this.isMultistream
|
|
365
379
|
});
|
|
366
380
|
newMqa.videoTransmit.push(videoSender);
|
|
367
381
|
(0, _mqaUtil.getVideoSenderMqa)({
|
|
368
382
|
videoSender: videoShareSender,
|
|
369
383
|
statsResults: this.statsResults,
|
|
370
384
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
371
|
-
baseMediaType: 'video-share-send'
|
|
385
|
+
baseMediaType: 'video-share-send',
|
|
386
|
+
isMultistream: this.isMultistream
|
|
372
387
|
});
|
|
373
388
|
newMqa.videoTransmit.push(videoShareSender);
|
|
374
389
|
(0, _mqaUtil.getVideoReceiverMqa)({
|
|
375
390
|
videoReceiver: videoReceiver,
|
|
376
391
|
statsResults: this.statsResults,
|
|
377
392
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
378
|
-
baseMediaType: 'video-recv'
|
|
393
|
+
baseMediaType: 'video-recv',
|
|
394
|
+
isMultistream: this.isMultistream
|
|
379
395
|
});
|
|
380
396
|
newMqa.videoReceive.push(videoReceiver);
|
|
381
397
|
(0, _mqaUtil.getVideoReceiverMqa)({
|
|
382
398
|
videoReceiver: videoShareReceiver,
|
|
383
399
|
statsResults: this.statsResults,
|
|
384
400
|
lastMqaDataSent: this.lastMqaDataSent,
|
|
385
|
-
baseMediaType: 'video-share-recv'
|
|
401
|
+
baseMediaType: 'video-share-recv',
|
|
402
|
+
isMultistream: this.isMultistream
|
|
386
403
|
});
|
|
387
404
|
newMqa.videoReceive.push(videoShareReceiver);
|
|
388
405
|
|
|
@@ -396,7 +413,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
396
413
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
397
414
|
mediaType: mediaType
|
|
398
415
|
});
|
|
399
|
-
|
|
416
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.SEND_DIRECTION)) {
|
|
417
|
+
newMqa.audioTransmit[0].streams.push(audioSenderStream);
|
|
418
|
+
}
|
|
400
419
|
_this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
|
|
401
420
|
} else if (mediaType.startsWith('audio-share-send')) {
|
|
402
421
|
var _audioSenderStream = (0, _lodash.cloneDeep)(_config.emptyAudioTransmitStream);
|
|
@@ -406,7 +425,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
406
425
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
407
426
|
mediaType: mediaType
|
|
408
427
|
});
|
|
409
|
-
|
|
428
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.SEND_DIRECTION)) {
|
|
429
|
+
newMqa.audioTransmit[1].streams.push(_audioSenderStream);
|
|
430
|
+
}
|
|
410
431
|
_this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
|
|
411
432
|
} else if (mediaType.startsWith('audio-recv')) {
|
|
412
433
|
var audioReceiverStream = (0, _lodash.cloneDeep)(_config.emptyAudioReceiveStream);
|
|
@@ -416,7 +437,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
416
437
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
417
438
|
mediaType: mediaType
|
|
418
439
|
});
|
|
419
|
-
|
|
440
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.RECEIVE_DIRECTION)) {
|
|
441
|
+
newMqa.audioReceive[0].streams.push(audioReceiverStream);
|
|
442
|
+
}
|
|
420
443
|
_this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
|
|
421
444
|
} else if (mediaType.startsWith('audio-share-recv')) {
|
|
422
445
|
var _audioReceiverStream = (0, _lodash.cloneDeep)(_config.emptyAudioReceiveStream);
|
|
@@ -426,7 +449,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
426
449
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
427
450
|
mediaType: mediaType
|
|
428
451
|
});
|
|
429
|
-
|
|
452
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.RECEIVE_DIRECTION)) {
|
|
453
|
+
newMqa.audioReceive[1].streams.push(_audioReceiverStream);
|
|
454
|
+
}
|
|
430
455
|
_this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
|
|
431
456
|
} else if (mediaType.startsWith('video-send-layer')) {
|
|
432
457
|
// We only want the stream-specific stats we get with video-send-layer-0, video-send-layer-1, etc.
|
|
@@ -437,7 +462,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
437
462
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
438
463
|
mediaType: mediaType
|
|
439
464
|
});
|
|
440
|
-
|
|
465
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.SEND_DIRECTION)) {
|
|
466
|
+
newMqa.videoTransmit[0].streams.push(videoSenderStream);
|
|
467
|
+
}
|
|
441
468
|
_this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
|
|
442
469
|
} else if (mediaType.startsWith('video-share-send')) {
|
|
443
470
|
var _videoSenderStream = (0, _lodash.cloneDeep)(_config.emptyVideoTransmitStream);
|
|
@@ -447,7 +474,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
447
474
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
448
475
|
mediaType: mediaType
|
|
449
476
|
});
|
|
450
|
-
|
|
477
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.SEND_DIRECTION)) {
|
|
478
|
+
newMqa.videoTransmit[1].streams.push(_videoSenderStream);
|
|
479
|
+
}
|
|
451
480
|
_this3.lastMqaDataSent[mediaType].send = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].send);
|
|
452
481
|
} else if (mediaType.startsWith('video-recv')) {
|
|
453
482
|
var videoReceiverStream = (0, _lodash.cloneDeep)(_config.emptyVideoReceiveStream);
|
|
@@ -457,7 +486,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
457
486
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
458
487
|
mediaType: mediaType
|
|
459
488
|
});
|
|
460
|
-
|
|
489
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.RECEIVE_DIRECTION)) {
|
|
490
|
+
newMqa.videoReceive[0].streams.push(videoReceiverStream);
|
|
491
|
+
}
|
|
461
492
|
_this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
|
|
462
493
|
} else if (mediaType.startsWith('video-share-recv')) {
|
|
463
494
|
var _videoReceiverStream = (0, _lodash.cloneDeep)(_config.emptyVideoReceiveStream);
|
|
@@ -467,7 +498,9 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
467
498
|
lastMqaDataSent: _this3.lastMqaDataSent,
|
|
468
499
|
mediaType: mediaType
|
|
469
500
|
});
|
|
470
|
-
|
|
501
|
+
if ((0, _mqaUtil.isStreamRequested)(_this3.statsResults, mediaType, _constants.STATS.RECEIVE_DIRECTION)) {
|
|
502
|
+
newMqa.videoReceive[1].streams.push(_videoReceiverStream);
|
|
503
|
+
}
|
|
471
504
|
_this3.lastMqaDataSent[mediaType].recv = (0, _lodash.cloneDeep)(_this3.statsResults[mediaType].recv);
|
|
472
505
|
}
|
|
473
506
|
});
|
|
@@ -494,6 +527,12 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
494
527
|
});
|
|
495
528
|
}
|
|
496
529
|
newMqa.networkType = this.statsResults.connectionType.local.networkType;
|
|
530
|
+
newMqa.intervalMetadata.screenWidth = window.screen.width;
|
|
531
|
+
newMqa.intervalMetadata.screenHeight = window.screen.height;
|
|
532
|
+
newMqa.intervalMetadata.screenResolution = Math.round(window.screen.width * window.screen.height / 256);
|
|
533
|
+
newMqa.intervalMetadata.appWindowWidth = window.innerWidth;
|
|
534
|
+
newMqa.intervalMetadata.appWindowHeight = window.innerHeight;
|
|
535
|
+
newMqa.intervalMetadata.appWindowSize = Math.round(window.innerWidth * window.innerHeight / 256);
|
|
497
536
|
this.mqaSentCount += 1;
|
|
498
537
|
newMqa.intervalNumber = this.mqaSentCount;
|
|
499
538
|
this.resetStatsResults();
|
|
@@ -919,10 +958,13 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
919
958
|
this.statsResults[mediaType][sendrecvType].encoderImplementation = result.encoderImplementation;
|
|
920
959
|
this.statsResults[mediaType][sendrecvType].qualityLimitationReason = result.qualityLimitationReason;
|
|
921
960
|
this.statsResults[mediaType][sendrecvType].qualityLimitationResolutionChanges = result.qualityLimitationResolutionChanges;
|
|
922
|
-
this.statsResults[mediaType][sendrecvType].
|
|
961
|
+
this.statsResults[mediaType][sendrecvType].totalRtxPacketsSent = result.retransmittedPacketsSent;
|
|
962
|
+
this.statsResults[mediaType][sendrecvType].totalRtxBytesSent = result.retransmittedBytesSent;
|
|
923
963
|
this.statsResults[mediaType][sendrecvType].totalBytesSent = result.bytesSent;
|
|
924
964
|
this.statsResults[mediaType][sendrecvType].headerBytesSent = result.headerBytesSent;
|
|
925
965
|
this.statsResults[mediaType][sendrecvType].retransmittedBytesSent = result.retransmittedBytesSent;
|
|
966
|
+
this.statsResults[mediaType][sendrecvType].isRequested = result.isRequested;
|
|
967
|
+
this.statsResults[mediaType][sendrecvType].lastRequestedUpdateTimestamp = result.lastRequestedUpdateTimestamp;
|
|
926
968
|
this.statsResults[mediaType][sendrecvType].requestedBitrate = result.requestedBitrate;
|
|
927
969
|
this.statsResults[mediaType][sendrecvType].requestedFrameSize = result.requestedFrameSize;
|
|
928
970
|
}
|
|
@@ -978,6 +1020,10 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
978
1020
|
}
|
|
979
1021
|
}
|
|
980
1022
|
}
|
|
1023
|
+
if (mediaType.startsWith('video-recv')) {
|
|
1024
|
+
this.statsResults[mediaType][sendrecvType].isActiveSpeaker = result.isActiveSpeaker;
|
|
1025
|
+
this.statsResults[mediaType][sendrecvType].lastActiveSpeakerTimestamp = result.lastActiveSpeakerUpdateTimestamp;
|
|
1026
|
+
}
|
|
981
1027
|
|
|
982
1028
|
// Check the over all packet Lost ratio
|
|
983
1029
|
this.statsResults[mediaType][sendrecvType].currentPacketLossRatio = currentPacketsLost > 0 ? currentPacketsLost / (packetsReceivedDiff + currentPacketsLost) : 0;
|
|
@@ -1013,6 +1059,8 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
1013
1059
|
this.statsResults[mediaType][sendrecvType].fecPacketsReceived = result.fecPacketsReceived;
|
|
1014
1060
|
this.statsResults[mediaType][sendrecvType].totalBytesReceived = result.bytesReceived;
|
|
1015
1061
|
this.statsResults[mediaType][sendrecvType].headerBytesReceived = result.headerBytesReceived;
|
|
1062
|
+
this.statsResults[mediaType][sendrecvType].totalRtxPacketsReceived = result.retransmittedPacketsReceived;
|
|
1063
|
+
this.statsResults[mediaType][sendrecvType].totalRtxBytesReceived = result.retransmittedBytesReceived;
|
|
1016
1064
|
this.statsResults[mediaType][sendrecvType].meanRtpJitter.push(result.jitter);
|
|
1017
1065
|
|
|
1018
1066
|
// Audio stats
|
|
@@ -1022,6 +1070,8 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
|
|
|
1022
1070
|
this.statsResults[mediaType][sendrecvType].totalSamplesReceived = result.totalSamplesReceived || 0;
|
|
1023
1071
|
this.statsResults[mediaType][sendrecvType].totalSamplesDecoded = result.totalSamplesDecoded || 0;
|
|
1024
1072
|
this.statsResults[mediaType][sendrecvType].concealedSamples = result.concealedSamples || 0;
|
|
1073
|
+
this.statsResults[mediaType][sendrecvType].isRequested = result.isRequested;
|
|
1074
|
+
this.statsResults[mediaType][sendrecvType].lastRequestedUpdateTimestamp = result.lastRequestedUpdateTimestamp;
|
|
1025
1075
|
}
|
|
1026
1076
|
}
|
|
1027
1077
|
}, {
|