@webex/plugin-meetings 3.0.0-beta.31 → 3.0.0-beta.310
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/README.md +46 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +52 -0
- package/dist/breakouts/edit-lock-error.js.map +1 -0
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +709 -35
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -11
- package/dist/config.js.map +1 -1
- package/dist/constants.js +233 -29
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +112 -1
- package/dist/index.js.map +1 -1
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +383 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +57 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +61 -116
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +82 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +3777 -2929
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +230 -124
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +260 -196
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +601 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +415 -115
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +72 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +102 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +13 -5
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -468
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +238 -49
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +29 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +44 -18
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +209 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/index.js +225 -59
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +17 -8
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +201 -156
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +62 -32
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +112 -97
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +95 -36
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +117 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +86 -78
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +11 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +1 -7
- package/dist/types/constants.d.ts +194 -24
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -4
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +67 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -48
- package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
- package/dist/types/meeting/index.d.ts +463 -510
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +99 -23
- package/dist/types/meeting/request.d.ts +72 -43
- package/dist/types/meeting/util.d.ts +101 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +98 -20
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +12 -4
- package/dist/types/metrics/index.d.ts +4 -119
- package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
- package/dist/types/multistream/receiveSlot.d.ts +13 -11
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +8 -29
- package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
- package/dist/types/multistream/sendSlotManager.d.ts +61 -0
- package/dist/types/reachability/index.d.ts +61 -7
- package/dist/types/reachability/request.d.ts +7 -3
- package/dist/types/reconnection-manager/index.d.ts +9 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +15 -11
- package/dist/types/roap/turnDiscovery.d.ts +21 -3
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +47 -0
- package/dist/types/statsAnalyzer/index.d.ts +7 -1
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +23 -20
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +42 -12
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/edit-lock-error.ts +25 -0
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +592 -20
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -10
- package/src/constants.ts +221 -19
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +40 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +413 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +102 -122
- package/src/media/properties.ts +87 -110
- package/src/meeting/in-meeting-actions.ts +163 -3
- package/src/meeting/index.ts +3132 -2541
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +229 -131
- package/src/meeting/request.ts +177 -121
- package/src/meeting/util.ts +588 -394
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +445 -123
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +80 -11
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +12 -4
- package/src/metrics/index.ts +1 -490
- package/src/multistream/mediaRequestManager.ts +289 -79
- package/src/multistream/receiveSlot.ts +31 -17
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +148 -30
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/index.ts +228 -37
- package/src/reachability/request.ts +17 -8
- package/src/reconnection-manager/index.ts +83 -56
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +63 -32
- package/src/roap/request.ts +100 -104
- package/src/roap/turnDiscovery.ts +48 -26
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +100 -0
- package/src/statsAnalyzer/index.ts +105 -91
- package/src/statsAnalyzer/mqaUtil.ts +13 -14
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +118 -28
- package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1395 -69
- package/test/unit/spec/breakouts/utils.js +52 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1304 -33
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +104 -37
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
- package/test/unit/spec/meeting/index.js +5216 -1956
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +408 -208
- package/test/unit/spec/meeting/request.js +483 -49
- package/test/unit/spec/meeting/utils.js +679 -64
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1011 -205
- package/test/unit/spec/meetings/utils.js +202 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
- package/test/unit/spec/multistream/receiveSlot.ts +28 -20
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +30 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/index.ts +549 -9
- package/test/unit/spec/reachability/request.js +68 -0
- package/test/unit/spec/reconnection-manager/index.js +85 -9
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +178 -64
- package/test/unit/spec/roap/request.ts +203 -85
- package/test/unit/spec/roap/turnDiscovery.ts +82 -36
- package/test/unit/spec/rtcMetrics/index.ts +73 -0
- package/test/unit/spec/stats-analyzer/index.js +136 -2
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -52
- package/dist/meeting/effectsState.js +0 -262
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/metrics/config.js +0 -299
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/meeting/effectsState.d.ts +0 -42
- package/dist/types/metrics/config.d.ts +0 -178
- package/src/index.js +0 -16
- package/src/meeting/effectsState.ts +0 -211
- package/src/metrics/config.ts +0 -495
- package/test/unit/spec/meeting/effectsState.js +0 -285
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
/* eslint-disable class-methods-use-this */
|
|
6
6
|
/* globals window */
|
|
7
|
-
import
|
|
7
|
+
import {uniq, mapValues, pick} from 'lodash';
|
|
8
8
|
|
|
9
9
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
10
|
+
import MeetingUtil from '../meeting/util';
|
|
11
|
+
|
|
10
12
|
import {ICE_GATHERING_STATE, CONNECTION_STATE, REACHABILITY} from '../constants';
|
|
11
13
|
|
|
12
14
|
import ReachabilityRequest from './request';
|
|
@@ -14,6 +16,50 @@ import ReachabilityRequest from './request';
|
|
|
14
16
|
const DEFAULT_TIMEOUT = 3000;
|
|
15
17
|
const VIDEO_MESH_TIMEOUT = 1000;
|
|
16
18
|
|
|
19
|
+
export type ReachabilityMetrics = {
|
|
20
|
+
reachability_public_udp_success: number;
|
|
21
|
+
reachability_public_udp_failed: number;
|
|
22
|
+
reachability_public_tcp_success: number;
|
|
23
|
+
reachability_public_tcp_failed: number;
|
|
24
|
+
reachability_vmn_udp_success: number;
|
|
25
|
+
reachability_vmn_udp_failed: number;
|
|
26
|
+
reachability_vmn_tcp_success: number;
|
|
27
|
+
reachability_vmn_tcp_failed: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// result for a specific transport protocol (like udp or tcp)
|
|
31
|
+
export type TransportResult = {
|
|
32
|
+
reachable?: 'true' | 'false';
|
|
33
|
+
latencyInMilliseconds?: string;
|
|
34
|
+
clientMediaIPs?: string[];
|
|
35
|
+
untested?: 'true';
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// reachability result for a specifc media cluster
|
|
39
|
+
type ReachabilityResult = {
|
|
40
|
+
udp: TransportResult;
|
|
41
|
+
tcp: TransportResult;
|
|
42
|
+
xtls: {
|
|
43
|
+
untested: 'true';
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
// this is the type that is required by the backend when we send them reachability results
|
|
47
|
+
export type ReachabilityResults = Record<string, ReachabilityResult>;
|
|
48
|
+
|
|
49
|
+
// this is the type used by Reachability class internally and stored in local storage
|
|
50
|
+
type InternalReachabilityResults = Record<
|
|
51
|
+
string,
|
|
52
|
+
ReachabilityResult & {
|
|
53
|
+
isVideoMesh?: boolean;
|
|
54
|
+
}
|
|
55
|
+
>;
|
|
56
|
+
|
|
57
|
+
export type ICECandidateResult = {
|
|
58
|
+
clusterId: string;
|
|
59
|
+
isVideoMesh: boolean;
|
|
60
|
+
elapsed?: string | null;
|
|
61
|
+
publicIPs?: string[];
|
|
62
|
+
};
|
|
17
63
|
/**
|
|
18
64
|
* @class Reachability
|
|
19
65
|
* @export
|
|
@@ -58,16 +104,20 @@ export default class Reachability {
|
|
|
58
104
|
* @async
|
|
59
105
|
* @memberof Reachability
|
|
60
106
|
*/
|
|
61
|
-
public async gatherReachability() {
|
|
107
|
+
public async gatherReachability(): Promise<InternalReachabilityResults> {
|
|
62
108
|
this.setup();
|
|
63
109
|
|
|
64
110
|
// Remove stored reachability results to ensure no stale data
|
|
65
111
|
// @ts-ignore
|
|
66
|
-
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.
|
|
112
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageResult);
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageJoinCookie);
|
|
67
115
|
|
|
68
116
|
// Fetch clusters and measure latency
|
|
69
117
|
try {
|
|
70
|
-
const clusters = await this.reachabilityRequest.getClusters(
|
|
118
|
+
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
|
|
119
|
+
MeetingUtil.getIpVersion(this.webex)
|
|
120
|
+
);
|
|
71
121
|
|
|
72
122
|
// Perform Reachability Check
|
|
73
123
|
const results = await this.performReachabilityCheck(clusters);
|
|
@@ -75,9 +125,15 @@ export default class Reachability {
|
|
|
75
125
|
// @ts-ignore
|
|
76
126
|
await this.webex.boundedStorage.put(
|
|
77
127
|
this.namespace,
|
|
78
|
-
REACHABILITY.
|
|
128
|
+
REACHABILITY.localStorageResult,
|
|
79
129
|
JSON.stringify(results)
|
|
80
130
|
);
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
await this.webex.boundedStorage.put(
|
|
133
|
+
this.namespace,
|
|
134
|
+
REACHABILITY.localStorageJoinCookie,
|
|
135
|
+
JSON.stringify(joinCookie)
|
|
136
|
+
);
|
|
81
137
|
|
|
82
138
|
LoggerProxy.logger.log(
|
|
83
139
|
'Reachability:index#gatherReachability --> Reachability checks completed'
|
|
@@ -93,25 +149,111 @@ export default class Reachability {
|
|
|
93
149
|
}
|
|
94
150
|
}
|
|
95
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Returns statistics about last reachability results. The returned value is an object
|
|
154
|
+
* with a flat list of properties so that it can be easily sent with metrics
|
|
155
|
+
*
|
|
156
|
+
* @returns {Promise} Promise with metrics values, it never rejects/throws.
|
|
157
|
+
*/
|
|
158
|
+
async getReachabilityMetrics(): Promise<ReachabilityMetrics> {
|
|
159
|
+
const stats: ReachabilityMetrics = {
|
|
160
|
+
reachability_public_udp_success: 0,
|
|
161
|
+
reachability_public_udp_failed: 0,
|
|
162
|
+
reachability_public_tcp_success: 0,
|
|
163
|
+
reachability_public_tcp_failed: 0,
|
|
164
|
+
reachability_vmn_udp_success: 0,
|
|
165
|
+
reachability_vmn_udp_failed: 0,
|
|
166
|
+
reachability_vmn_tcp_success: 0,
|
|
167
|
+
reachability_vmn_tcp_failed: 0,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const updateStats = (clusterType: 'public' | 'vmn', result: ReachabilityResult) => {
|
|
171
|
+
if (result.udp?.reachable) {
|
|
172
|
+
const outcome = result.udp.reachable === 'true' ? 'success' : 'failed';
|
|
173
|
+
stats[`reachability_${clusterType}_udp_${outcome}`] += 1;
|
|
174
|
+
}
|
|
175
|
+
if (result.tcp?.reachable) {
|
|
176
|
+
const outcome = result.tcp.reachable === 'true' ? 'success' : 'failed';
|
|
177
|
+
stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
const resultsJson = await this.webex.boundedStorage.get(
|
|
184
|
+
REACHABILITY.namespace,
|
|
185
|
+
REACHABILITY.localStorageResult
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const internalResults: InternalReachabilityResults = JSON.parse(resultsJson);
|
|
189
|
+
|
|
190
|
+
Object.values(internalResults).forEach((result) => {
|
|
191
|
+
updateStats(result.isVideoMesh ? 'vmn' : 'public', result);
|
|
192
|
+
});
|
|
193
|
+
} catch (e) {
|
|
194
|
+
// empty storage, that's ok
|
|
195
|
+
LoggerProxy.logger.warn(
|
|
196
|
+
'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',
|
|
197
|
+
e
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return stats;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Reachability results as an object in the format that backend expects
|
|
206
|
+
*
|
|
207
|
+
* @returns {any} reachability results that need to be sent to the backend
|
|
208
|
+
*/
|
|
209
|
+
async getReachabilityResults(): Promise<ReachabilityResults | undefined> {
|
|
210
|
+
let results: ReachabilityResults;
|
|
211
|
+
|
|
212
|
+
// these are the only props that backend needs in the reachability results:
|
|
213
|
+
const reachabilityResultsProps: Array<keyof ReachabilityResult> = ['udp', 'tcp', 'xtls'];
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
// @ts-ignore
|
|
217
|
+
const resultsJson = await this.webex.boundedStorage.get(
|
|
218
|
+
REACHABILITY.namespace,
|
|
219
|
+
REACHABILITY.localStorageResult
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const internalResults: InternalReachabilityResults = JSON.parse(resultsJson);
|
|
223
|
+
|
|
224
|
+
results = mapValues(internalResults, (result) => pick(result, reachabilityResultsProps));
|
|
225
|
+
} catch (e) {
|
|
226
|
+
// empty storage, that's ok
|
|
227
|
+
LoggerProxy.logger.warn(
|
|
228
|
+
'Roap:request#attachReachabilityData --> Error parsing reachability data: ',
|
|
229
|
+
e
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return results;
|
|
234
|
+
}
|
|
235
|
+
|
|
96
236
|
/**
|
|
97
237
|
* fetches reachability data and checks for cluster reachability
|
|
98
238
|
* @returns {boolean}
|
|
99
239
|
* @public
|
|
100
240
|
* @memberof Reachability
|
|
101
241
|
*/
|
|
102
|
-
async
|
|
242
|
+
async isAnyPublicClusterReachable() {
|
|
103
243
|
let reachable = false;
|
|
104
244
|
// @ts-ignore
|
|
105
245
|
const reachabilityData = await this.webex.boundedStorage
|
|
106
|
-
.get(this.namespace, REACHABILITY.
|
|
246
|
+
.get(this.namespace, REACHABILITY.localStorageResult)
|
|
107
247
|
.catch(() => {});
|
|
108
248
|
|
|
109
249
|
if (reachabilityData) {
|
|
110
250
|
try {
|
|
111
|
-
const reachabilityResults = JSON.parse(reachabilityData);
|
|
251
|
+
const reachabilityResults: InternalReachabilityResults = JSON.parse(reachabilityData);
|
|
112
252
|
|
|
113
253
|
reachable = Object.values(reachabilityResults).some(
|
|
114
|
-
(result
|
|
254
|
+
(result) =>
|
|
255
|
+
!result.isVideoMesh &&
|
|
256
|
+
(result.udp?.reachable === 'true' || result.tcp?.reachable === 'true')
|
|
115
257
|
);
|
|
116
258
|
} catch (e) {
|
|
117
259
|
LoggerProxy.logger.error(
|
|
@@ -131,7 +273,7 @@ export default class Reachability {
|
|
|
131
273
|
* @memberof Reachability
|
|
132
274
|
*/
|
|
133
275
|
private buildPeerConnectionConfig(cluster: any) {
|
|
134
|
-
const iceServers =
|
|
276
|
+
const iceServers = uniq(cluster.udp).map((url) => ({
|
|
135
277
|
username: '',
|
|
136
278
|
credential: '',
|
|
137
279
|
urls: [url],
|
|
@@ -192,7 +334,7 @@ export default class Reachability {
|
|
|
192
334
|
* @private
|
|
193
335
|
* @memberof Reachability
|
|
194
336
|
*/
|
|
195
|
-
private getLocalSDPForClusters(clusterList: object) {
|
|
337
|
+
private getLocalSDPForClusters(clusterList: object): Promise<InternalReachabilityResults> {
|
|
196
338
|
let clusters: any[] = [...Object.keys(clusterList)];
|
|
197
339
|
|
|
198
340
|
clusters = clusters.map(async (key) => {
|
|
@@ -205,18 +347,17 @@ export default class Reachability {
|
|
|
205
347
|
peerConnection.begin = Date.now();
|
|
206
348
|
peerConnection.setLocalDescription(description);
|
|
207
349
|
|
|
208
|
-
return this.iceGatheringState(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
});
|
|
350
|
+
return this.iceGatheringState(peerConnection, cluster.isVideoMesh).catch(
|
|
351
|
+
(iceGatheringStateError) => {
|
|
352
|
+
LoggerProxy.logger.log(
|
|
353
|
+
`Reachability:index#getLocalSDPForClusters --> Error in getLocalSDP : ${iceGatheringStateError}`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
);
|
|
216
357
|
});
|
|
217
358
|
|
|
218
359
|
return Promise.all(clusters)
|
|
219
|
-
.then(this.
|
|
360
|
+
.then(this.parseIceResultsToInternalReachabilityResults)
|
|
220
361
|
.then((reachabilityLatencyResults) => {
|
|
221
362
|
this.logUnreachableClusters();
|
|
222
363
|
|
|
@@ -292,6 +433,8 @@ export default class Reachability {
|
|
|
292
433
|
`Reachability:index#onIceCandidate --> Successfully pinged ${peerConnection.key}:`,
|
|
293
434
|
elapsed
|
|
294
435
|
);
|
|
436
|
+
// order is important
|
|
437
|
+
this.addPublicIP(peerConnection, e.candidate.address);
|
|
295
438
|
this.setLatencyAndClose(peerConnection, elapsed);
|
|
296
439
|
}
|
|
297
440
|
};
|
|
@@ -303,14 +446,17 @@ export default class Reachability {
|
|
|
303
446
|
* speed.
|
|
304
447
|
* @private
|
|
305
448
|
* @param {RTCPeerConnection} peerConnection
|
|
306
|
-
* @param {
|
|
449
|
+
* @param {boolean} isVideoMesh
|
|
307
450
|
* @returns {Promise}
|
|
308
451
|
*/
|
|
309
|
-
private iceGatheringState(peerConnection: RTCPeerConnection,
|
|
452
|
+
private iceGatheringState(peerConnection: RTCPeerConnection, isVideoMesh: boolean) {
|
|
310
453
|
const ELAPSED = 'elapsed';
|
|
311
454
|
|
|
312
|
-
|
|
455
|
+
const timeout = isVideoMesh ? VIDEO_MESH_TIMEOUT : DEFAULT_TIMEOUT;
|
|
456
|
+
|
|
457
|
+
return new Promise<ICECandidateResult>((resolve) => {
|
|
313
458
|
const peerConnectionProxy = new window.Proxy(peerConnection, {
|
|
459
|
+
// eslint-disable-next-line require-jsdoc
|
|
314
460
|
get(target, property) {
|
|
315
461
|
const targetMember = target[property];
|
|
316
462
|
|
|
@@ -323,8 +469,14 @@ export default class Reachability {
|
|
|
323
469
|
set: (target, property, value) => {
|
|
324
470
|
// only intercept elapsed property
|
|
325
471
|
if (property === ELAPSED) {
|
|
326
|
-
|
|
327
|
-
|
|
472
|
+
resolve({
|
|
473
|
+
// @ts-ignore
|
|
474
|
+
clusterId: peerConnection.key,
|
|
475
|
+
isVideoMesh,
|
|
476
|
+
// @ts-ignore
|
|
477
|
+
publicIPs: target.publicIPs,
|
|
478
|
+
elapsed: value,
|
|
479
|
+
});
|
|
328
480
|
|
|
329
481
|
return true;
|
|
330
482
|
}
|
|
@@ -345,6 +497,8 @@ export default class Reachability {
|
|
|
345
497
|
|
|
346
498
|
// Close any open peerConnections
|
|
347
499
|
if (peerConnectionProxy.connectionState !== CLOSED) {
|
|
500
|
+
// order is important
|
|
501
|
+
this.addPublicIP(peerConnectionProxy, null);
|
|
348
502
|
this.setLatencyAndClose(peerConnectionProxy, null);
|
|
349
503
|
}
|
|
350
504
|
}, timeout);
|
|
@@ -369,29 +523,39 @@ export default class Reachability {
|
|
|
369
523
|
|
|
370
524
|
/**
|
|
371
525
|
* Calculates time to establish connection
|
|
372
|
-
* @param {
|
|
526
|
+
* @param {Array<ICECandidateResult>} iceResults iceResults
|
|
373
527
|
* @returns {object} reachabilityMap
|
|
374
|
-
* @
|
|
528
|
+
* @protected
|
|
375
529
|
* @memberof Reachability
|
|
376
530
|
*/
|
|
377
|
-
|
|
531
|
+
protected parseIceResultsToInternalReachabilityResults(
|
|
532
|
+
iceResults: Array<ICECandidateResult>
|
|
533
|
+
): InternalReachabilityResults {
|
|
378
534
|
const reachabilityMap = {};
|
|
379
535
|
|
|
380
|
-
iceResults.forEach(({clusterId, elapsed}) => {
|
|
381
|
-
|
|
536
|
+
iceResults.forEach(({clusterId, isVideoMesh, elapsed, publicIPs}) => {
|
|
537
|
+
const latencyResult = {};
|
|
382
538
|
|
|
383
|
-
if (elapsed
|
|
384
|
-
latencyResult
|
|
539
|
+
if (!elapsed) {
|
|
540
|
+
Object.assign(latencyResult, {reachable: 'false'});
|
|
385
541
|
} else {
|
|
386
|
-
latencyResult
|
|
542
|
+
Object.assign(latencyResult, {
|
|
387
543
|
reachable: 'true',
|
|
388
544
|
latencyInMilliseconds: elapsed.toString(),
|
|
389
|
-
};
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (publicIPs) {
|
|
549
|
+
Object.assign(latencyResult, {
|
|
550
|
+
clientMediaIPs: publicIPs,
|
|
551
|
+
});
|
|
390
552
|
}
|
|
391
553
|
|
|
392
554
|
reachabilityMap[clusterId] = {
|
|
393
555
|
udp: latencyResult,
|
|
394
|
-
tcp:
|
|
556
|
+
tcp: {untested: 'true'},
|
|
557
|
+
xtls: {untested: 'true'},
|
|
558
|
+
isVideoMesh,
|
|
395
559
|
};
|
|
396
560
|
});
|
|
397
561
|
|
|
@@ -401,11 +565,11 @@ export default class Reachability {
|
|
|
401
565
|
/**
|
|
402
566
|
* fetches reachability data
|
|
403
567
|
* @param {object} clusterList
|
|
404
|
-
* @returns {Promise<
|
|
568
|
+
* @returns {Promise<InternalReachabilityResults>} reachability check results
|
|
405
569
|
* @private
|
|
406
570
|
* @memberof Reachability
|
|
407
571
|
*/
|
|
408
|
-
private performReachabilityCheck(clusterList: object) {
|
|
572
|
+
private performReachabilityCheck(clusterList: object): Promise<InternalReachabilityResults> {
|
|
409
573
|
if (!clusterList || !Object.keys(clusterList).length) {
|
|
410
574
|
return Promise.resolve({});
|
|
411
575
|
}
|
|
@@ -432,6 +596,33 @@ export default class Reachability {
|
|
|
432
596
|
});
|
|
433
597
|
}
|
|
434
598
|
|
|
599
|
+
/**
|
|
600
|
+
* Adds public IP (client media IPs)
|
|
601
|
+
* @param {RTCPeerConnection} peerConnection
|
|
602
|
+
* @param {string} publicIP
|
|
603
|
+
* @returns {void}
|
|
604
|
+
*/
|
|
605
|
+
protected addPublicIP(peerConnection: RTCPeerConnection, publicIP?: string | null) {
|
|
606
|
+
const modifiedPeerConnection: RTCPeerConnection & {publicIPs?: string[]} = peerConnection;
|
|
607
|
+
const {CLOSED} = CONNECTION_STATE;
|
|
608
|
+
|
|
609
|
+
if (modifiedPeerConnection.connectionState === CLOSED) {
|
|
610
|
+
LoggerProxy.logger.log(
|
|
611
|
+
`Reachability:index#addPublicIP --> Attempting to set publicIP of ${publicIP} on closed peerConnection.`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (publicIP) {
|
|
616
|
+
if (modifiedPeerConnection.publicIPs) {
|
|
617
|
+
modifiedPeerConnection.publicIPs.push(publicIP);
|
|
618
|
+
} else {
|
|
619
|
+
modifiedPeerConnection.publicIPs = [publicIP];
|
|
620
|
+
}
|
|
621
|
+
} else {
|
|
622
|
+
modifiedPeerConnection.publicIPs = null;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
435
626
|
/**
|
|
436
627
|
* Records latency and closes the peerConnection
|
|
437
628
|
* @param {RTCPeerConnection} peerConnection
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
2
|
-
import {HTTP_VERBS, RESOURCE, API} from '../constants';
|
|
2
|
+
import {HTTP_VERBS, RESOURCE, API, IP_VERSION} from '../constants';
|
|
3
3
|
|
|
4
4
|
export interface ClusterNode {
|
|
5
5
|
isVideoMesh: boolean;
|
|
@@ -28,31 +28,40 @@ class ReachabilityRequest {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Gets the cluster information
|
|
32
32
|
*
|
|
33
|
-
* @param {
|
|
33
|
+
* @param {IP_VERSION} ipVersion information about current ip network we're on
|
|
34
34
|
* @returns {Promise}
|
|
35
35
|
*/
|
|
36
|
-
getClusters = (): Promise<ClusterList> =>
|
|
36
|
+
getClusters = (ipVersion?: IP_VERSION): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
37
37
|
this.webex
|
|
38
38
|
.request({
|
|
39
39
|
method: HTTP_VERBS.GET,
|
|
40
40
|
shouldRefreshAccessToken: false,
|
|
41
41
|
api: API.CALLIOPEDISCOVERY,
|
|
42
42
|
resource: RESOURCE.CLUSTERS,
|
|
43
|
+
qs: {
|
|
44
|
+
JCSupport: 1,
|
|
45
|
+
ipver: ipVersion,
|
|
46
|
+
},
|
|
43
47
|
})
|
|
44
48
|
.then((res) => {
|
|
45
|
-
const {clusters} = res.body;
|
|
49
|
+
const {clusters, joinCookie} = res.body;
|
|
46
50
|
|
|
47
51
|
Object.keys(clusters).forEach((key) => {
|
|
48
|
-
clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
|
|
52
|
+
clusters[key].isVideoMesh = !!res.body.clusterClasses?.hybridMedia?.includes(key);
|
|
49
53
|
});
|
|
50
54
|
|
|
51
55
|
LoggerProxy.logger.log(
|
|
52
|
-
`Reachability:request#getClusters --> get clusters successful:${JSON.stringify(
|
|
56
|
+
`Reachability:request#getClusters --> get clusters (ipver=${ipVersion}) successful:${JSON.stringify(
|
|
57
|
+
clusters
|
|
58
|
+
)}`
|
|
53
59
|
);
|
|
54
60
|
|
|
55
|
-
return
|
|
61
|
+
return {
|
|
62
|
+
clusters,
|
|
63
|
+
joinCookie,
|
|
64
|
+
};
|
|
56
65
|
});
|
|
57
66
|
|
|
58
67
|
/**
|
|
@@ -18,10 +18,9 @@ import {
|
|
|
18
18
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
19
19
|
import ReconnectionError from '../common/errors/reconnection';
|
|
20
20
|
import ReconnectInProgress from '../common/errors/reconnection-in-progress';
|
|
21
|
-
import {eventType, reconnection, errorObjects} from '../metrics/config';
|
|
22
|
-
import Media from '../media';
|
|
23
21
|
import Metrics from '../metrics';
|
|
24
22
|
import Meeting from '../meeting';
|
|
23
|
+
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
* Used to indicate that the reconnect logic needs to be retried.
|
|
@@ -231,6 +230,32 @@ export default class ReconnectionManager {
|
|
|
231
230
|
this.meeting = null;
|
|
232
231
|
}
|
|
233
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Stop the local share stream.
|
|
235
|
+
*
|
|
236
|
+
* @param {string} reason a {@link SHARE_STOPPED_REASON}
|
|
237
|
+
* @returns {undefined}
|
|
238
|
+
* @private
|
|
239
|
+
* @memberof ReconnectionManager
|
|
240
|
+
*/
|
|
241
|
+
private async stopLocalShareStream(reason: string) {
|
|
242
|
+
await this.meeting.unpublishStreams([
|
|
243
|
+
this.meeting.mediaProperties.shareVideoStream,
|
|
244
|
+
this.meeting.mediaProperties.shareAudioStream,
|
|
245
|
+
]);
|
|
246
|
+
Trigger.trigger(
|
|
247
|
+
this.meeting,
|
|
248
|
+
{
|
|
249
|
+
file: 'reconnection-manager/index',
|
|
250
|
+
function: 'stopLocalShareStream',
|
|
251
|
+
},
|
|
252
|
+
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
|
|
253
|
+
{
|
|
254
|
+
reason,
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
234
259
|
/**
|
|
235
260
|
* @public
|
|
236
261
|
* @memberof ReconnectionManager
|
|
@@ -302,9 +327,13 @@ export default class ReconnectionManager {
|
|
|
302
327
|
LoggerProxy.logger.info(
|
|
303
328
|
'ReconnectionManager:index#reconnect --> Sending reconnect start metric.'
|
|
304
329
|
);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
330
|
+
|
|
331
|
+
// @ts-ignore
|
|
332
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
333
|
+
name: 'client.media.reconnecting',
|
|
334
|
+
options: {
|
|
335
|
+
meetingId: this.meeting.id,
|
|
336
|
+
},
|
|
308
337
|
});
|
|
309
338
|
}
|
|
310
339
|
|
|
@@ -314,10 +343,16 @@ export default class ReconnectionManager {
|
|
|
314
343
|
LoggerProxy.logger.info(
|
|
315
344
|
'ReconnectionManager:index#reconnect --> Sending reconnect success metric.'
|
|
316
345
|
);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
346
|
+
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
349
|
+
name: 'client.media.recovered',
|
|
350
|
+
payload: {
|
|
351
|
+
recoveredBy: 'new',
|
|
352
|
+
},
|
|
353
|
+
options: {
|
|
354
|
+
meetingId: this.meeting.id,
|
|
355
|
+
},
|
|
321
356
|
});
|
|
322
357
|
})
|
|
323
358
|
.catch((reconnectError) => {
|
|
@@ -341,23 +376,24 @@ export default class ReconnectionManager {
|
|
|
341
376
|
'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
|
|
342
377
|
);
|
|
343
378
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
379
|
+
// @ts-ignore
|
|
380
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
381
|
+
name: 'client.call.aborted',
|
|
382
|
+
payload: {
|
|
348
383
|
errors: [
|
|
349
384
|
{
|
|
350
|
-
category:
|
|
385
|
+
category: 'expected',
|
|
351
386
|
errorCode: 2008,
|
|
352
387
|
fatal: true,
|
|
353
|
-
name:
|
|
388
|
+
name: 'media-engine',
|
|
354
389
|
shownToUser: false,
|
|
355
390
|
},
|
|
356
391
|
],
|
|
357
392
|
},
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
393
|
+
options: {
|
|
394
|
+
meetingId: this.meeting.id,
|
|
395
|
+
},
|
|
396
|
+
});
|
|
361
397
|
if (reconnectError instanceof NeedsRejoinError) {
|
|
362
398
|
// send call aborded event with catogery as expected as we are trying to rejoin
|
|
363
399
|
|
|
@@ -385,6 +421,12 @@ export default class ReconnectionManager {
|
|
|
385
421
|
'ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.'
|
|
386
422
|
);
|
|
387
423
|
|
|
424
|
+
const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
|
|
425
|
+
|
|
426
|
+
if (wasSharing) {
|
|
427
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEDIA_RECONNECTION);
|
|
428
|
+
}
|
|
429
|
+
|
|
388
430
|
if (networkDisconnect) {
|
|
389
431
|
try {
|
|
390
432
|
await this.reconnectMercuryWebSocket();
|
|
@@ -401,29 +443,29 @@ export default class ReconnectionManager {
|
|
|
401
443
|
}
|
|
402
444
|
}
|
|
403
445
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
446
|
+
if (!this.webex.credentials.isUnverifiedGuest) {
|
|
447
|
+
try {
|
|
448
|
+
LoggerProxy.logger.info(
|
|
449
|
+
'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
|
|
450
|
+
);
|
|
451
|
+
await this.webex.meetings.syncMeetings();
|
|
452
|
+
} catch (syncError) {
|
|
453
|
+
LoggerProxy.logger.info(
|
|
454
|
+
'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
|
|
455
|
+
syncError
|
|
456
|
+
);
|
|
457
|
+
throw new NeedsRetryError(syncError);
|
|
458
|
+
}
|
|
417
459
|
}
|
|
418
460
|
|
|
419
461
|
// TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object
|
|
420
462
|
// So that on rejoin it known what parametrs it was using
|
|
421
463
|
if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {
|
|
422
464
|
LoggerProxy.logger.info(
|
|
423
|
-
'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely
|
|
465
|
+
'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely.'
|
|
424
466
|
);
|
|
425
467
|
|
|
426
|
-
throw new Error('Unable to rejoin a meeting already ended or inactive
|
|
468
|
+
throw new Error('Unable to rejoin a meeting already ended or inactive.');
|
|
427
469
|
}
|
|
428
470
|
|
|
429
471
|
LoggerProxy.logger.info(
|
|
@@ -475,24 +517,7 @@ export default class ReconnectionManager {
|
|
|
475
517
|
LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
|
|
476
518
|
|
|
477
519
|
if (wasSharing) {
|
|
478
|
-
|
|
479
|
-
Media.stopTracks(this.meeting.mediaProperties.shareTrack);
|
|
480
|
-
this.meeting.isSharing = false;
|
|
481
|
-
if (this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
|
|
482
|
-
this.meeting.shareStatus = SHARE_STATUS.NO_SHARE;
|
|
483
|
-
}
|
|
484
|
-
this.meeting.mediaProperties.mediaDirection.sendShare = false;
|
|
485
|
-
Trigger.trigger(
|
|
486
|
-
this.meeting,
|
|
487
|
-
{
|
|
488
|
-
file: 'reconnection-manager/index',
|
|
489
|
-
function: 'rejoinMeeting',
|
|
490
|
-
},
|
|
491
|
-
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
|
|
492
|
-
{
|
|
493
|
-
reason: SHARE_STOPPED_REASON.MEETING_REJOIN,
|
|
494
|
-
}
|
|
495
|
-
);
|
|
520
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEETING_REJOIN);
|
|
496
521
|
}
|
|
497
522
|
} catch (joinError) {
|
|
498
523
|
this.rejoinAttempts += 1;
|
|
@@ -538,8 +563,8 @@ export default class ReconnectionManager {
|
|
|
538
563
|
'ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'
|
|
539
564
|
);
|
|
540
565
|
|
|
541
|
-
// do the TURN server discovery again since the TURN server might change
|
|
542
|
-
const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true);
|
|
566
|
+
// do the TURN server discovery again and ignore reachability results since the TURN server might change
|
|
567
|
+
const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true, true);
|
|
543
568
|
|
|
544
569
|
const iceServers = [];
|
|
545
570
|
|
|
@@ -555,9 +580,11 @@ export default class ReconnectionManager {
|
|
|
555
580
|
|
|
556
581
|
// resend media requests
|
|
557
582
|
if (this.meeting.isMultistream) {
|
|
558
|
-
Object.values(this.meeting.mediaRequestManagers).forEach(
|
|
559
|
-
|
|
560
|
-
|
|
583
|
+
Object.values(this.meeting.mediaRequestManagers).forEach(
|
|
584
|
+
(mediaRequestManager: MediaRequestManager) => {
|
|
585
|
+
mediaRequestManager.clearPreviousRequests();
|
|
586
|
+
mediaRequestManager.commit();
|
|
587
|
+
}
|
|
561
588
|
);
|
|
562
589
|
}
|
|
563
590
|
}
|