@webex/plugin-meetings 3.1.0 → 3.3.0
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/common/errors/{reconnection-in-progress.js → reconnection-not-started.js} +27 -15
- package/dist/common/errors/reconnection-not-started.js.map +1 -0
- package/dist/constants.js +12 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +7 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +10 -0
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/properties.js +102 -57
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +6 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +543 -467
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +27 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/util.js +9 -16
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +37 -49
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meeting-info/util.js +304 -267
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +334 -298
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.js +6 -27
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/index.js +6 -0
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +138 -109
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/request.js +3 -27
- package/dist/roap/request.js.map +1 -1
- package/dist/statsAnalyzer/index.js +4 -0
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +3 -0
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/common/errors/reconnection-not-started.d.ts +13 -0
- package/dist/{constants.d.ts → types/constants.d.ts} +11 -2
- package/dist/types/index.d.ts +19 -0
- package/dist/{media → types/media}/properties.d.ts +26 -2
- package/dist/{meeting → types/meeting}/in-meeting-actions.d.ts +6 -0
- package/dist/{meeting → types/meeting}/index.d.ts +5 -6
- package/dist/{meeting → types/meeting}/locusMediaRequest.d.ts +1 -0
- package/dist/{meeting → types/meeting}/util.d.ts +3 -0
- package/dist/{meeting → types/meeting}/voicea-meeting.d.ts +3 -2
- package/dist/{meeting-info → types/meeting-info}/index.d.ts +1 -1
- package/dist/{meeting-info → types/meeting-info}/meeting-info-v2.d.ts +1 -1
- package/dist/types/meeting-info/util.d.ts +49 -0
- package/dist/types/meeting-info/utilv2.d.ts +65 -0
- package/dist/{meetings → types/meetings}/index.d.ts +1 -16
- package/dist/{reconnection-manager → types/reconnection-manager}/index.d.ts +4 -14
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/common/errors/reconnection-not-started.ts +25 -0
- package/src/constants.ts +12 -4
- package/src/index.ts +30 -0
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +16 -0
- package/src/media/properties.ts +67 -15
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +121 -98
- package/src/meeting/locusMediaRequest.ts +31 -0
- package/src/meeting/util.ts +9 -16
- package/src/meeting/voicea-meeting.ts +44 -46
- package/src/meeting-info/util.ts +241 -233
- package/src/meeting-info/utilv2.ts +250 -244
- package/src/meetings/index.ts +8 -25
- package/src/reachability/index.ts +3 -0
- package/src/reconnection-manager/index.ts +128 -105
- package/src/roap/request.ts +1 -24
- package/src/statsAnalyzer/index.ts +4 -0
- package/src/statsAnalyzer/mqaUtil.ts +5 -0
- package/test/unit/spec/locus-info/controlsUtils.js +20 -0
- package/test/unit/spec/locus-info/index.js +21 -0
- package/test/unit/spec/media/properties.ts +145 -140
- package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
- package/test/unit/spec/meeting/index.js +243 -97
- package/test/unit/spec/meeting/locusMediaRequest.ts +49 -0
- package/test/unit/spec/meeting/utils.js +3 -10
- package/test/unit/spec/meeting/voicea-meeting.ts +5 -14
- package/test/unit/spec/meetings/index.js +27 -8
- package/test/unit/spec/reconnection-manager/index.js +127 -39
- package/test/unit/spec/roap/request.ts +0 -37
- package/test/unit/spec/stats-analyzer/index.js +11 -0
- package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
- package/dist/common/errors/reconnection-in-progress.js.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/meeting-info/util.d.ts +0 -2
- package/dist/meeting-info/utilv2.d.ts +0 -2
- package/src/common/errors/reconnection-in-progress.ts +0 -8
- /package/dist/{annotation → types/annotation}/annotation.types.d.ts +0 -0
- /package/dist/{annotation → types/annotation}/constants.d.ts +0 -0
- /package/dist/{annotation → types/annotation}/index.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/breakout.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/collection.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/edit-lock-error.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/events.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/index.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/request.d.ts +0 -0
- /package/dist/{breakouts → types/breakouts}/utils.d.ts +0 -0
- /package/dist/{common → types/common}/browser-detection.d.ts +0 -0
- /package/dist/{common → types/common}/collection.d.ts +0 -0
- /package/dist/{common → types/common}/config.d.ts +0 -0
- /package/dist/{common → types/common}/errors/captcha-error.d.ts +0 -0
- /package/dist/{common → types/common}/errors/intent-to-join.d.ts +0 -0
- /package/dist/{common → types/common}/errors/join-meeting.d.ts +0 -0
- /package/dist/{common → types/common}/errors/media.d.ts +0 -0
- /package/dist/{common → types/common}/errors/no-meeting-info.d.ts +0 -0
- /package/dist/{common → types/common}/errors/parameter.d.ts +0 -0
- /package/dist/{common → types/common}/errors/password-error.d.ts +0 -0
- /package/dist/{common → types/common}/errors/permission.d.ts +0 -0
- /package/dist/{common → types/common}/errors/reclaim-host-role-errors.d.ts +0 -0
- /package/dist/{common → types/common}/errors/reconnection.d.ts +0 -0
- /package/dist/{common → types/common}/errors/stats.d.ts +0 -0
- /package/dist/{common → types/common}/errors/webex-errors.d.ts +0 -0
- /package/dist/{common → types/common}/errors/webex-meetings-error.d.ts +0 -0
- /package/dist/{common → types/common}/events/events-scope.d.ts +0 -0
- /package/dist/{common → types/common}/events/events.d.ts +0 -0
- /package/dist/{common → types/common}/events/trigger-proxy.d.ts +0 -0
- /package/dist/{common → types/common}/events/util.d.ts +0 -0
- /package/dist/{common → types/common}/logs/logger-config.d.ts +0 -0
- /package/dist/{common → types/common}/logs/logger-proxy.d.ts +0 -0
- /package/dist/{common → types/common}/logs/request.d.ts +0 -0
- /package/dist/{common → types/common}/queue.d.ts +0 -0
- /package/dist/{config.d.ts → types/config.d.ts} +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/constants.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/enums.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/index.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/types.d.ts +0 -0
- /package/dist/{controls-options-manager → types/controls-options-manager}/util.d.ts +0 -0
- /package/dist/{interceptors → types/interceptors}/index.d.ts +0 -0
- /package/dist/{interceptors → types/interceptors}/locusRetry.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/collection.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/index.d.ts +0 -0
- /package/dist/{interpretation → types/interpretation}/siLanguage.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/controlsUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/embeddedAppsUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/fullState.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/hostUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/index.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/infoUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/mediaSharesUtils.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/parser.d.ts +0 -0
- /package/dist/{locus-info → types/locus-info}/selfUtils.d.ts +0 -0
- /package/dist/{media → types/media}/MediaConnectionAwaiter.d.ts +0 -0
- /package/dist/{media → types/media}/index.d.ts +0 -0
- /package/dist/{media → types/media}/util.d.ts +0 -0
- /package/dist/{mediaQualityMetrics → types/mediaQualityMetrics}/config.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/muteState.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/request.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/request.type.d.ts +0 -0
- /package/dist/{meeting → types/meeting}/state.d.ts +0 -0
- /package/dist/{meeting-info → types/meeting-info}/collection.d.ts +0 -0
- /package/dist/{meeting-info → types/meeting-info}/request.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/collection.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/meetings.types.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/request.d.ts +0 -0
- /package/dist/{meetings → types/meetings}/util.d.ts +0 -0
- /package/dist/{member → types/member}/index.d.ts +0 -0
- /package/dist/{member → types/member}/types.d.ts +0 -0
- /package/dist/{member → types/member}/util.d.ts +0 -0
- /package/dist/{members → types/members}/collection.d.ts +0 -0
- /package/dist/{members → types/members}/index.d.ts +0 -0
- /package/dist/{members → types/members}/request.d.ts +0 -0
- /package/dist/{members → types/members}/types.d.ts +0 -0
- /package/dist/{members → types/members}/util.d.ts +0 -0
- /package/dist/{metrics → types/metrics}/constants.d.ts +0 -0
- /package/dist/{metrics → types/metrics}/index.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/mediaRequestManager.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/receiveSlot.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/receiveSlotManager.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/remoteMedia.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/remoteMediaGroup.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/remoteMediaManager.d.ts +0 -0
- /package/dist/{multistream → types/multistream}/sendSlotManager.d.ts +0 -0
- /package/dist/{networkQualityMonitor → types/networkQualityMonitor}/index.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/index.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/request.d.ts +0 -0
- /package/dist/{personal-meeting-room → types/personal-meeting-room}/util.d.ts +0 -0
- /package/dist/{reachability → types/reachability}/clusterReachability.d.ts +0 -0
- /package/dist/{reachability → types/reachability}/index.d.ts +0 -0
- /package/dist/{reachability → types/reachability}/request.d.ts +0 -0
- /package/dist/{reachability → types/reachability}/util.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/constants.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/reactions.d.ts +0 -0
- /package/dist/{reactions → types/reactions}/reactions.type.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/enums.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/index.d.ts +0 -0
- /package/dist/{recording-controller → types/recording-controller}/util.d.ts +0 -0
- /package/dist/{roap → types/roap}/index.d.ts +0 -0
- /package/dist/{roap → types/roap}/request.d.ts +0 -0
- /package/dist/{roap → types/roap}/turnDiscovery.d.ts +0 -0
- /package/dist/{rtcMetrics → types/rtcMetrics}/constants.d.ts +0 -0
- /package/dist/{rtcMetrics → types/rtcMetrics}/index.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/global.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/index.d.ts +0 -0
- /package/dist/{statsAnalyzer → types/statsAnalyzer}/mqaUtil.d.ts +0 -0
- /package/dist/{transcription → types/transcription}/index.d.ts +0 -0
- /package/dist/{webinar → types/webinar}/collection.d.ts +0 -0
- /package/dist/{webinar → types/webinar}/index.d.ts +0 -0
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
RECONNECTION_STATE,
|
|
18
18
|
} from '../constants';
|
|
19
19
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
20
|
-
import
|
|
20
|
+
import ReconnectionError from '../common/errors/reconnection';
|
|
21
|
+
import ReconnectionNotStartedError from '../common/errors/reconnection-not-started';
|
|
21
22
|
import Metrics from '../metrics';
|
|
22
23
|
import Meeting from '../meeting';
|
|
23
24
|
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
24
|
-
import ReconnectionError from '../common/errors/reconnection';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Used to indicate that the reconnect logic needs to be retried.
|
|
@@ -73,7 +73,6 @@ export default class ReconnectionManager {
|
|
|
73
73
|
rejoinAttempts: any;
|
|
74
74
|
shareStatus: any;
|
|
75
75
|
status: any;
|
|
76
|
-
tryCount: any;
|
|
77
76
|
webex: any;
|
|
78
77
|
/**
|
|
79
78
|
* @param {Meeting} meeting
|
|
@@ -102,13 +101,6 @@ export default class ReconnectionManager {
|
|
|
102
101
|
* @memberof ReconnectionManager
|
|
103
102
|
*/
|
|
104
103
|
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
105
|
-
/**
|
|
106
|
-
* @instance
|
|
107
|
-
* @type {Number}
|
|
108
|
-
* @private
|
|
109
|
-
* @memberof ReconnectionManager
|
|
110
|
-
*/
|
|
111
|
-
this.tryCount = RECONNECTION.STATE.DEFAULT_TRY_COUNT;
|
|
112
104
|
/**
|
|
113
105
|
* @instance
|
|
114
106
|
* @type {Object}
|
|
@@ -131,7 +123,7 @@ export default class ReconnectionManager {
|
|
|
131
123
|
|
|
132
124
|
// @ts-ignore
|
|
133
125
|
this.maxRejoinAttempts = meeting.config.reconnection.maxRejoinAttempts;
|
|
134
|
-
this.rejoinAttempts =
|
|
126
|
+
this.rejoinAttempts = 0;
|
|
135
127
|
// @ts-ignore
|
|
136
128
|
this.autoRejoinEnabled = meeting.config.reconnection.autoRejoin;
|
|
137
129
|
|
|
@@ -217,8 +209,7 @@ export default class ReconnectionManager {
|
|
|
217
209
|
*/
|
|
218
210
|
public reset() {
|
|
219
211
|
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
220
|
-
this.
|
|
221
|
-
this.rejoinAttempts = RECONNECTION.STATE.DEFAULT_TRY_COUNT;
|
|
212
|
+
this.rejoinAttempts = 0;
|
|
222
213
|
}
|
|
223
214
|
|
|
224
215
|
/**
|
|
@@ -265,43 +256,30 @@ export default class ReconnectionManager {
|
|
|
265
256
|
return this.status === RECONNECTION.STATE.IN_PROGRESS;
|
|
266
257
|
}
|
|
267
258
|
|
|
268
|
-
/**
|
|
269
|
-
* Sets the reconnection status
|
|
270
|
-
*
|
|
271
|
-
* @public
|
|
272
|
-
* @param {RECONNECTION_STATE} status
|
|
273
|
-
* @memberof ReconnectionManager
|
|
274
|
-
* @returns {undefined}
|
|
275
|
-
*/
|
|
276
|
-
public setStatus(status: RECONNECTION_STATE) {
|
|
277
|
-
this.status = status;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
259
|
/**
|
|
281
260
|
* @returns {Boolean}
|
|
282
|
-
* @throws {
|
|
261
|
+
* @throws {ReconnectInProgress, ReconnectionDisabled}
|
|
283
262
|
* @private
|
|
284
263
|
* @memberof ReconnectionManager
|
|
285
264
|
*/
|
|
286
|
-
private
|
|
265
|
+
private canStartReconnection() {
|
|
287
266
|
if (this.meeting.config.reconnection.enabled) {
|
|
288
|
-
if (
|
|
289
|
-
this.status === RECONNECTION.STATE.DEFAULT_STATUS ||
|
|
290
|
-
this.status === RECONNECTION.STATE.COMPLETE
|
|
291
|
-
) {
|
|
267
|
+
if (this.status === RECONNECTION.STATE.DEFAULT_STATUS) {
|
|
292
268
|
return true;
|
|
293
269
|
}
|
|
294
270
|
|
|
295
271
|
LoggerProxy.logger.info(
|
|
296
|
-
'ReconnectionManager:index#
|
|
272
|
+
'ReconnectionManager:index#canStartReconnection --> Reconnection already in progress.'
|
|
297
273
|
);
|
|
298
274
|
|
|
299
|
-
|
|
275
|
+
return false;
|
|
300
276
|
}
|
|
301
277
|
|
|
302
|
-
LoggerProxy.logger.info(
|
|
278
|
+
LoggerProxy.logger.info(
|
|
279
|
+
'ReconnectionManager:index#canStartReconnection --> Reconnection is not enabled.'
|
|
280
|
+
);
|
|
303
281
|
|
|
304
|
-
|
|
282
|
+
return false;
|
|
305
283
|
}
|
|
306
284
|
|
|
307
285
|
/**
|
|
@@ -309,105 +287,152 @@ export default class ReconnectionManager {
|
|
|
309
287
|
* @param {Object} reconnectOptions
|
|
310
288
|
* @param {boolean} [reconnectOptions.networkDisconnect=false] indicates if a network disconnect event happened
|
|
311
289
|
* @param {boolean} [reconnectOptions.networkRetry=false] indicates if we are retrying the reconnect
|
|
290
|
+
* @param {Function} [completionCallback] callback that gets called when reconnection is started successfully
|
|
312
291
|
* @returns {Promise}
|
|
313
292
|
* @public
|
|
314
293
|
* @memberof ReconnectionManager
|
|
315
294
|
*/
|
|
316
|
-
public async reconnect(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
295
|
+
public async reconnect(
|
|
296
|
+
{
|
|
297
|
+
networkDisconnect = false,
|
|
298
|
+
networkRetry = false,
|
|
299
|
+
}: {
|
|
300
|
+
networkDisconnect?: boolean;
|
|
301
|
+
networkRetry?: boolean;
|
|
302
|
+
} = {},
|
|
303
|
+
completionCallback: (() => Promise<void>) | undefined = undefined
|
|
304
|
+
) {
|
|
323
305
|
LoggerProxy.logger.info(
|
|
324
306
|
`ReconnectionManager:index#reconnect --> Reconnection start for meeting ${this.meeting.id}.`
|
|
325
307
|
);
|
|
326
|
-
// First, validate that we can reconnect, if not, it will throw an error
|
|
327
|
-
try {
|
|
328
|
-
this.validate();
|
|
329
|
-
} catch (error) {
|
|
330
|
-
LoggerProxy.logger.info(
|
|
331
|
-
'ReconnectionManager:index#reconnect --> Reconnection unable to begin.',
|
|
332
|
-
error
|
|
333
|
-
);
|
|
334
|
-
throw error;
|
|
335
|
-
}
|
|
336
308
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
309
|
+
const triggerEvent = (event, payload = undefined) =>
|
|
310
|
+
Trigger.trigger(
|
|
311
|
+
this.meeting,
|
|
312
|
+
{
|
|
313
|
+
file: 'reconnection-manager/index',
|
|
314
|
+
function: 'reconnect',
|
|
315
|
+
},
|
|
316
|
+
event,
|
|
317
|
+
payload
|
|
341
318
|
);
|
|
342
319
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
name: 'client.media.reconnecting',
|
|
346
|
-
options: {
|
|
347
|
-
meetingId: this.meeting.id,
|
|
348
|
-
},
|
|
349
|
-
});
|
|
320
|
+
if (!this.canStartReconnection()) {
|
|
321
|
+
throw new ReconnectionNotStartedError();
|
|
350
322
|
}
|
|
351
323
|
|
|
352
324
|
try {
|
|
353
|
-
|
|
354
|
-
} catch (err) {
|
|
355
|
-
LoggerProxy.logger.info(
|
|
356
|
-
'ReconnectionManager:index#reconnect --> Reachability failed, continuing with reconnection attempt, err: ',
|
|
357
|
-
err
|
|
358
|
-
);
|
|
359
|
-
}
|
|
325
|
+
this.status = RECONNECTION.STATE.IN_PROGRESS;
|
|
360
326
|
|
|
361
|
-
|
|
362
|
-
const media = await this.executeReconnection({networkDisconnect});
|
|
327
|
+
triggerEvent(EVENT_TRIGGERS.MEETING_RECONNECTION_STARTING);
|
|
363
328
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (reconnectError instanceof NeedsRetryError) {
|
|
329
|
+
if (!networkRetry) {
|
|
330
|
+
// Only log START metrics on the initial reconnect
|
|
367
331
|
LoggerProxy.logger.info(
|
|
368
|
-
'ReconnectionManager:index#reconnect -->
|
|
332
|
+
'ReconnectionManager:index#reconnect --> Sending reconnect start metric.'
|
|
369
333
|
);
|
|
370
|
-
// Reset our reconnect status since we are looping back to the beginning
|
|
371
|
-
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
372
334
|
|
|
373
|
-
//
|
|
374
|
-
|
|
335
|
+
// @ts-ignore
|
|
336
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
337
|
+
name: 'client.media.reconnecting',
|
|
338
|
+
options: {
|
|
339
|
+
meetingId: this.meeting.id,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
375
342
|
}
|
|
376
343
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
344
|
+
try {
|
|
345
|
+
await this.webex.meetings.startReachability();
|
|
346
|
+
} catch (err) {
|
|
347
|
+
LoggerProxy.logger.info(
|
|
348
|
+
'ReconnectionManager:index#reconnect --> Reachability failed, continuing with reconnection attempt, err: ',
|
|
349
|
+
err
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
await this.executeReconnection({networkDisconnect});
|
|
355
|
+
} catch (reconnectError) {
|
|
356
|
+
if (reconnectError instanceof NeedsRetryError) {
|
|
357
|
+
LoggerProxy.logger.info(
|
|
358
|
+
'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
|
|
359
|
+
);
|
|
360
|
+
// Reset our reconnect status since we are looping back to the beginning
|
|
361
|
+
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
362
|
+
|
|
363
|
+
// This is a network retry, so we should not log START metrics again
|
|
364
|
+
await this.reconnect({networkDisconnect: true, networkRetry: true}, completionCallback);
|
|
365
|
+
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Reconnect has failed
|
|
370
|
+
LoggerProxy.logger.error(
|
|
371
|
+
'ReconnectionManager:index#reconnect --> Reconnection failed.',
|
|
372
|
+
reconnectError.message
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
// send call aborted event with category as expected as we are trying to rejoin
|
|
376
|
+
// @ts-ignore
|
|
377
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
378
|
+
name: 'client.call.aborted',
|
|
379
|
+
payload: {
|
|
380
|
+
errors: [
|
|
381
|
+
{
|
|
382
|
+
category: 'expected',
|
|
383
|
+
errorCode: 2008,
|
|
384
|
+
fatal: true,
|
|
385
|
+
name: 'media-engine',
|
|
386
|
+
shownToUser: false,
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
options: {
|
|
391
|
+
meetingId: this.meeting.id,
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
if (reconnectError instanceof NeedsRejoinError && this.autoRejoinEnabled) {
|
|
396
|
+
await this.rejoinMeeting(reconnectError.wasSharing);
|
|
397
|
+
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
throw reconnectError;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// finalize the reconnection process by calling the completionCallback
|
|
405
|
+
if (completionCallback) {
|
|
406
|
+
await completionCallback();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
triggerEvent(EVENT_TRIGGERS.MEETING_RECONNECTION_SUCCESS);
|
|
385
410
|
|
|
386
|
-
// send call aborted event with catogery as expected as we are trying to rejoin
|
|
387
411
|
// @ts-ignore
|
|
388
412
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
389
|
-
name: 'client.
|
|
413
|
+
name: 'client.media.recovered',
|
|
390
414
|
payload: {
|
|
391
|
-
|
|
392
|
-
{
|
|
393
|
-
category: 'expected',
|
|
394
|
-
errorCode: 2008,
|
|
395
|
-
fatal: true,
|
|
396
|
-
name: 'media-engine',
|
|
397
|
-
shownToUser: false,
|
|
398
|
-
},
|
|
399
|
-
],
|
|
415
|
+
recoveredBy: 'new',
|
|
400
416
|
},
|
|
401
417
|
options: {
|
|
402
418
|
meetingId: this.meeting.id,
|
|
403
419
|
},
|
|
404
420
|
});
|
|
421
|
+
} catch (error) {
|
|
422
|
+
triggerEvent(EVENT_TRIGGERS.MEETING_RECONNECTION_FAILURE, {
|
|
423
|
+
error: new ReconnectionError('Reconnection failure event', error),
|
|
424
|
+
});
|
|
405
425
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
426
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_RECONNECT_FAILURE, {
|
|
427
|
+
correlation_id: this.meeting.correlationId,
|
|
428
|
+
locus_id: this.meeting.locusUrl.split('/').pop(),
|
|
429
|
+
reason: error.message,
|
|
430
|
+
stack: error.stack,
|
|
431
|
+
});
|
|
409
432
|
|
|
410
|
-
throw
|
|
433
|
+
throw new ReconnectionError('Reconnection failure event', error);
|
|
434
|
+
} finally {
|
|
435
|
+
this.reset();
|
|
411
436
|
}
|
|
412
437
|
}
|
|
413
438
|
|
|
@@ -420,8 +445,6 @@ export default class ReconnectionManager {
|
|
|
420
445
|
* @memberof ReconnectionManager
|
|
421
446
|
*/
|
|
422
447
|
private async executeReconnection({networkDisconnect = false}: {networkDisconnect?: boolean}) {
|
|
423
|
-
this.status = RECONNECTION.STATE.IN_PROGRESS;
|
|
424
|
-
|
|
425
448
|
LoggerProxy.logger.info(
|
|
426
449
|
'ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.'
|
|
427
450
|
);
|
package/src/roap/request.ts
CHANGED
|
@@ -61,7 +61,7 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
61
61
|
ipVersion?: IP_VERSION;
|
|
62
62
|
locusMediaRequest?: LocusMediaRequest;
|
|
63
63
|
}) {
|
|
64
|
-
const {roapMessage, locusSelfUrl, mediaId,
|
|
64
|
+
const {roapMessage, locusSelfUrl, mediaId, locusMediaRequest, ipVersion} = options;
|
|
65
65
|
|
|
66
66
|
if (!mediaId) {
|
|
67
67
|
LoggerProxy.logger.info('Roap:request#sendRoap --> sending empty mediaID');
|
|
@@ -82,14 +82,6 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
82
82
|
`Roap:request#sendRoap --> ${locusSelfUrl} \n ${roapMessage.messageType} \n seq:${roapMessage.seq}`
|
|
83
83
|
);
|
|
84
84
|
|
|
85
|
-
// @ts-ignore
|
|
86
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
87
|
-
name: 'client.locus.media.request',
|
|
88
|
-
options: {
|
|
89
|
-
meetingId,
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
85
|
return locusMediaRequest
|
|
94
86
|
.send({
|
|
95
87
|
type: 'RoapMessage',
|
|
@@ -101,13 +93,6 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
101
93
|
ipVersion,
|
|
102
94
|
})
|
|
103
95
|
.then((res) => {
|
|
104
|
-
// @ts-ignore
|
|
105
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
106
|
-
name: 'client.locus.media.response',
|
|
107
|
-
options: {
|
|
108
|
-
meetingId,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
96
|
// always it will be the first mediaConnection Object
|
|
112
97
|
const mediaConnections =
|
|
113
98
|
res.body.mediaConnections &&
|
|
@@ -131,14 +116,6 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
131
116
|
};
|
|
132
117
|
})
|
|
133
118
|
.catch((err) => {
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
136
|
-
name: 'client.locus.media.response',
|
|
137
|
-
options: {
|
|
138
|
-
meetingId,
|
|
139
|
-
rawError: err,
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
119
|
LoggerProxy.logger.error(`Roap:request#sendRoap --> Error:`, err);
|
|
143
120
|
LoggerProxy.logger.error(
|
|
144
121
|
`Roap:request#sendRoapRequest --> roapMessage that caused error:${JSON.stringify(
|
|
@@ -1004,6 +1004,8 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
1004
1004
|
this.statsResults[mediaType][sendrecvType].headerBytesSent = result.headerBytesSent;
|
|
1005
1005
|
this.statsResults[mediaType][sendrecvType].retransmittedBytesSent =
|
|
1006
1006
|
result.retransmittedBytesSent;
|
|
1007
|
+
this.statsResults[mediaType][sendrecvType].requestedBitrate = result.requestedBitrate;
|
|
1008
|
+
this.statsResults[mediaType][sendrecvType].requestedFrameSize = result.requestedFrameSize;
|
|
1007
1009
|
}
|
|
1008
1010
|
}
|
|
1009
1011
|
|
|
@@ -1116,6 +1118,8 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
1116
1118
|
|
|
1117
1119
|
this.statsResults[mediaType][sendrecvType].lastPacketReceivedTimestamp =
|
|
1118
1120
|
result.lastPacketReceivedTimestamp;
|
|
1121
|
+
this.statsResults[mediaType][sendrecvType].requestedBitrate = result.requestedBitrate;
|
|
1122
|
+
this.statsResults[mediaType][sendrecvType].requestedFrameSize = result.requestedFrameSize;
|
|
1119
1123
|
|
|
1120
1124
|
// From Thin
|
|
1121
1125
|
this.statsResults[mediaType][sendrecvType].totalNackCount = result.nackCount;
|
|
@@ -216,6 +216,8 @@ export const getAudioSenderStreamMqa = ({
|
|
|
216
216
|
statsResults[mediaType][sendrecvType].totalKeyFramesEncoded - lastFramesEncoded || 0;
|
|
217
217
|
audioSenderStream.requestedKeyFrames =
|
|
218
218
|
statsResults[mediaType][sendrecvType].totalFirCount - lastFirCount || 0;
|
|
219
|
+
|
|
220
|
+
audioSenderStream.requestedBitrate = statsResults[mediaType][sendrecvType].requestedBitrate || 0;
|
|
219
221
|
};
|
|
220
222
|
|
|
221
223
|
export const getVideoReceiverMqa = ({
|
|
@@ -437,4 +439,7 @@ export const getVideoSenderStreamMqa = ({
|
|
|
437
439
|
videoSenderStream.transmittedWidth = statsResults[mediaType][sendrecvType].width || 0;
|
|
438
440
|
videoSenderStream.transmittedFrameSize =
|
|
439
441
|
(videoSenderStream.transmittedHeight * videoSenderStream.transmittedWidth) / 256;
|
|
442
|
+
videoSenderStream.requestedBitrate = statsResults[mediaType][sendrecvType].requestedBitrate || 0;
|
|
443
|
+
videoSenderStream.requestedFrameSize =
|
|
444
|
+
statsResults[mediaType][sendrecvType].requestedFrameSize || 0;
|
|
440
445
|
};
|
|
@@ -269,6 +269,26 @@ describe('plugin-meetings', () => {
|
|
|
269
269
|
assert.equal(updates.hasInterpretationChanged, false);
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
it('returns hasManualCaptionChanged = true when it has changed', () => {
|
|
273
|
+
const newControls = {
|
|
274
|
+
manualCaptionControl: {enabled: false},
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const {updates} = ControlsUtils.getControls({manualCaptionControl: {enabled: true}}, newControls);
|
|
278
|
+
|
|
279
|
+
assert.equal(updates.hasManualCaptionChanged, true);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('returns hasManualCaptionChanged = false when it has not changed', () => {
|
|
283
|
+
const newControls = {
|
|
284
|
+
manualCaptionControl: {enabled: true},
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const {updates} = ControlsUtils.getControls({manualCaptionControl: {enabled: true}}, newControls);
|
|
288
|
+
|
|
289
|
+
assert.equal(updates.hasManualCaptionChanged, false);
|
|
290
|
+
});
|
|
291
|
+
|
|
272
292
|
describe('videoEnabled', () => {
|
|
273
293
|
const testVideoEnabled = (oldControls, newControls, updatedProperty) => {
|
|
274
294
|
const result = ControlsUtils.getControls(oldControls, newControls);
|
|
@@ -467,6 +467,27 @@ describe('plugin-meetings', () => {
|
|
|
467
467
|
);
|
|
468
468
|
});
|
|
469
469
|
|
|
470
|
+
it('should update the manual caption state', () => {
|
|
471
|
+
locusInfo.emitScoped = sinon.stub();
|
|
472
|
+
locusInfo.controls = {
|
|
473
|
+
manualCaptionControl: {enabled: false},
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
locusInfo.updateControls({manualCaptionControl: { enabled: true, }});
|
|
477
|
+
|
|
478
|
+
assert.calledWith(
|
|
479
|
+
locusInfo.emitScoped,
|
|
480
|
+
{
|
|
481
|
+
file: 'locus-info',
|
|
482
|
+
function: 'updateControls',
|
|
483
|
+
},
|
|
484
|
+
LOCUSINFO.EVENTS.CONTROLS_MEETING_MANUAL_CAPTION_UPDATED,
|
|
485
|
+
{
|
|
486
|
+
enabled: true,
|
|
487
|
+
}
|
|
488
|
+
);
|
|
489
|
+
});
|
|
490
|
+
|
|
470
491
|
it('should update the meetingContainerURL from null', () => {
|
|
471
492
|
locusInfo.controls = {
|
|
472
493
|
meetingContainer: {meetingContainerUrl: null},
|