@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.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/.eslintrc.js +6 -0
- package/README.md +12 -0
- package/babel.config.js +3 -0
- package/dist/annotation/constants.js +12 -20
- package/dist/annotation/constants.js.map +1 -1
- package/dist/annotation/index.js +25 -10
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +2 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/collection.js +1 -2
- package/dist/breakouts/collection.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +1 -2
- package/dist/breakouts/edit-lock-error.js.map +1 -1
- package/dist/breakouts/events.js +1 -2
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +13 -14
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +1 -2
- package/dist/breakouts/request.js.map +1 -1
- package/dist/breakouts/utils.js +3 -6
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/browser-detection.js +2 -3
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +3 -4
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js +1 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +1 -2
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +1 -2
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +1 -2
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +1 -2
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/common/errors/no-meeting-info.js +50 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/parameter.js +3 -4
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +1 -2
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +1 -2
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/common/errors/reclaim-host-role-errors.js +154 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/reconnection-in-progress.js +1 -2
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +1 -2
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +1 -2
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/{types/common → common}/errors/webex-errors.d.ts +13 -1
- package/dist/common/errors/webex-errors.js +35 -16
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +1 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +1 -2
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +1 -2
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js +1 -2
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js +1 -2
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js +1 -2
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -2
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/{types/common → common}/logs/request.d.ts +3 -1
- package/dist/common/logs/request.js +8 -5
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +2 -4
- package/dist/common/queue.js.map +1 -1
- package/dist/{types/config.d.ts → config.d.ts} +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/{types/constants.d.ts → constants.d.ts} +72 -15
- package/dist/constants.js +254 -371
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +3 -6
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +7 -10
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +27 -32
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +1 -2
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.d.ts +2 -0
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.d.ts +27 -0
- package/dist/interceptors/locusRetry.js +94 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +1 -2
- package/dist/interpretation/collection.js.map +1 -1
- package/dist/interpretation/index.js +2 -3
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +2 -3
- package/dist/interpretation/siLanguage.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +12 -13
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js +3 -4
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js +1 -2
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js +1 -2
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/{types/locus-info → locus-info}/index.d.ts +1 -1
- package/dist/locus-info/index.js +63 -38
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +3 -4
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +16 -3
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/{types/locus-info → locus-info}/parser.d.ts +3 -2
- package/dist/locus-info/parser.js +48 -31
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +7 -6
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +15 -10
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +16 -7
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -2
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.d.ts +241 -0
- package/dist/mediaQualityMetrics/config.js +135 -339
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/{types/meeting → meeting}/in-meeting-actions.d.ts +4 -0
- package/dist/meeting/in-meeting-actions.js +18 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/{types/meeting → meeting}/index.d.ts +331 -44
- package/dist/meeting/index.js +2639 -1367
- package/dist/meeting/index.js.map +1 -1
- package/dist/{types/meeting → meeting}/locusMediaRequest.d.ts +1 -2
- package/dist/meeting/locusMediaRequest.js +4 -5
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +2 -4
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/{types/meeting → meeting}/request.d.ts +4 -1
- package/dist/meeting/request.js +47 -32
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/state.js +1 -2
- package/dist/meeting/state.js.map +1 -1
- package/dist/{types/meeting → meeting}/util.d.ts +26 -1
- package/dist/meeting/util.js +83 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +16 -0
- package/dist/meeting/voicea-meeting.js +169 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/collection.js +3 -4
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/{types/meeting-info → meeting-info}/index.d.ts +7 -0
- package/dist/meeting-info/index.js +53 -27
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/{types/meeting-info → meeting-info}/meeting-info-v2.d.ts +1 -0
- package/dist/meeting-info/meeting-info-v2.js +52 -33
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +8 -8
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +12 -9
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/{types/meetings → meetings}/collection.d.ts +9 -0
- package/dist/meetings/collection.js +21 -5
- package/dist/meetings/collection.js.map +1 -1
- package/dist/{types/meetings → meetings}/index.d.ts +45 -16
- package/dist/meetings/index.js +166 -74
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +2 -3
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +3 -10
- package/dist/meetings/util.js.map +1 -1
- package/dist/{types/member → member}/index.d.ts +1 -0
- package/dist/member/index.js +10 -3
- package/dist/member/index.js.map +1 -1
- package/dist/member/member.types.d.ts +11 -0
- package/dist/member/member.types.js +17 -0
- package/dist/member/member.types.js.map +1 -0
- package/dist/member/types.js +6 -8
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +12 -2
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +25 -8
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +2 -3
- package/dist/members/request.js.map +1 -1
- package/dist/{types/members → members}/types.d.ts +1 -0
- package/dist/members/types.js +3 -4
- package/dist/members/types.js.map +1 -1
- package/dist/{types/members → members}/util.d.ts +6 -1
- package/dist/members/util.js +18 -8
- package/dist/members/util.js.map +1 -1
- package/dist/{types/metrics → metrics}/constants.d.ts +15 -0
- package/dist/metrics/constants.js +16 -3
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +3 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +9 -11
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +3 -5
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +7 -9
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +7 -6
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/{types/multistream → multistream}/remoteMediaManager.d.ts +9 -1
- package/dist/multistream/remoteMediaManager.js +74 -36
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +9 -6
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +1 -2
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +2 -3
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -3
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js +1 -2
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +109 -0
- package/dist/reachability/clusterReachability.js +357 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.d.ts +105 -0
- package/dist/reachability/index.js +279 -436
- package/dist/reachability/index.js.map +1 -1
- package/dist/{types/reachability → reachability}/request.d.ts +1 -1
- package/dist/reachability/request.js +14 -11
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.d.ts +8 -0
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reactions/constants.js +1 -2
- package/dist/reactions/constants.js.map +1 -1
- package/dist/reactions/reactions.js +2 -4
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js +6 -8
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/{types/reconnection-manager → reconnection-manager}/index.d.ts +10 -0
- package/dist/reconnection-manager/index.js +129 -106
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +4 -5
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +43 -51
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +1 -2
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/{types/roap → roap}/index.d.ts +2 -1
- package/dist/roap/index.js +59 -28
- package/dist/roap/index.js.map +1 -1
- package/dist/{types/roap → roap}/request.d.ts +2 -1
- package/dist/roap/request.js +14 -22
- package/dist/roap/request.js.map +1 -1
- package/dist/{types/roap → roap}/turnDiscovery.d.ts +21 -4
- package/dist/roap/turnDiscovery.js +182 -89
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +1 -2
- package/dist/rtcMetrics/constants.js.map +1 -1
- package/dist/{types/rtcMetrics → rtcMetrics}/index.d.ts +15 -1
- package/dist/rtcMetrics/index.js +72 -12
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/global.js +1 -2
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/{types/statsAnalyzer → statsAnalyzer}/index.d.ts +28 -11
- package/dist/statsAnalyzer/index.js +371 -318
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
- package/dist/statsAnalyzer/mqaUtil.js +295 -162
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +1 -2
- package/dist/transcription/index.js.map +1 -1
- package/dist/webinar/collection.d.ts +16 -0
- package/dist/webinar/collection.js +43 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +68 -0
- package/dist/webinar/index.js.map +1 -0
- package/jest.config.js +3 -0
- package/package.json +44 -24
- package/process +1 -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 +19 -2
- package/src/common/logs/request.ts +5 -1
- package/src/config.ts +3 -5
- package/src/constants.ts +78 -8
- package/src/index.ts +4 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/locus-info/index.ts +52 -16
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/parser.ts +47 -21
- package/src/media/index.ts +8 -6
- package/src/media/properties.ts +17 -2
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +1692 -627
- package/src/meeting/request.ts +19 -1
- package/src/meeting/util.ts +102 -1
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/index.ts +47 -20
- package/src/meeting-info/meeting-info-v2.ts +32 -16
- package/src/meeting-info/util.ts +12 -9
- package/src/meeting-info/utilv2.ts +25 -15
- package/src/meetings/collection.ts +13 -0
- package/src/meetings/index.ts +112 -31
- package/src/meetings/util.ts +2 -8
- package/src/member/index.ts +9 -1
- package/src/member/member.types.ts +13 -0
- package/src/member/util.ts +14 -0
- package/src/members/index.ts +29 -2
- package/src/members/types.ts +1 -0
- package/src/members/util.ts +15 -1
- package/src/metrics/constants.ts +14 -0
- package/src/multistream/remoteMediaManager.ts +41 -4
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +221 -382
- package/src/reachability/request.ts +1 -1
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +87 -83
- package/src/roap/index.ts +60 -24
- package/src/roap/request.ts +4 -17
- package/src/roap/turnDiscovery.ts +112 -39
- package/src/rtcMetrics/index.ts +71 -5
- package/src/statsAnalyzer/index.ts +430 -427
- package/src/statsAnalyzer/mqaUtil.ts +317 -168
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +7 -7
- package/test/integration/spec/journey.js +88 -106
- package/test/integration/spec/space-meeting.js +10 -10
- package/test/unit/spec/breakouts/breakout.ts +2 -1
- package/test/unit/spec/breakouts/index.ts +7 -4
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/locus-info/index.js +206 -13
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
- package/test/unit/spec/locus-info/parser.js +54 -13
- package/test/unit/spec/locus-info/selfUtils.js +1 -1
- package/test/unit/spec/media/index.ts +25 -4
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
- package/test/unit/spec/meeting/index.js +4354 -1285
- package/test/unit/spec/meeting/request.js +63 -12
- package/test/unit/spec/meeting/utils.js +145 -10
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/index.js +180 -61
- package/test/unit/spec/meeting-info/meetinginfov2.js +216 -68
- package/test/unit/spec/meetings/collection.js +12 -0
- package/test/unit/spec/meetings/index.js +676 -195
- package/test/unit/spec/meetings/utils.js +35 -12
- package/test/unit/spec/member/index.js +8 -7
- package/test/unit/spec/member/util.js +32 -0
- package/test/unit/spec/members/index.js +130 -17
- package/test/unit/spec/members/utils.js +26 -0
- package/test/unit/spec/metrics/index.js +1 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +10 -2
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +505 -135
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +74 -17
- package/test/unit/spec/recording-controller/index.js +0 -1
- package/test/unit/spec/roap/index.ts +181 -61
- package/test/unit/spec/roap/request.ts +27 -3
- package/test/unit/spec/roap/turnDiscovery.ts +363 -102
- package/test/unit/spec/rtcMetrics/index.ts +57 -3
- package/test/unit/spec/stats-analyzer/index.js +1225 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +4 -4
- package/test/utils/webex-test-users.js +12 -4
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -365
- package/dist/types/reachability/index.d.ts +0 -158
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -24
- /package/dist/{types/annotation → annotation}/annotation.types.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/constants.d.ts +0 -0
- /package/dist/{types/annotation → annotation}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/breakout.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/collection.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/edit-lock-error.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/events.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/index.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/request.d.ts +0 -0
- /package/dist/{types/breakouts → breakouts}/utils.d.ts +0 -0
- /package/dist/{types/common → common}/browser-detection.d.ts +0 -0
- /package/dist/{types/common → common}/collection.d.ts +0 -0
- /package/dist/{types/common → common}/config.d.ts +0 -0
- /package/dist/{types/common → common}/errors/captcha-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/intent-to-join.d.ts +0 -0
- /package/dist/{types/common → common}/errors/join-meeting.d.ts +0 -0
- /package/dist/{types/common → common}/errors/media.d.ts +0 -0
- /package/dist/{types/common → common}/errors/parameter.d.ts +0 -0
- /package/dist/{types/common → common}/errors/password-error.d.ts +0 -0
- /package/dist/{types/common → common}/errors/permission.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection-in-progress.d.ts +0 -0
- /package/dist/{types/common → common}/errors/reconnection.d.ts +0 -0
- /package/dist/{types/common → common}/errors/stats.d.ts +0 -0
- /package/dist/{types/common → common}/errors/webex-meetings-error.d.ts +0 -0
- /package/dist/{types/common → common}/events/events-scope.d.ts +0 -0
- /package/dist/{types/common → common}/events/events.d.ts +0 -0
- /package/dist/{types/common → common}/events/trigger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/events/util.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-config.d.ts +0 -0
- /package/dist/{types/common → common}/logs/logger-proxy.d.ts +0 -0
- /package/dist/{types/common → common}/queue.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/constants.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/enums.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/index.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/types.d.ts +0 -0
- /package/dist/{types/controls-options-manager → controls-options-manager}/util.d.ts +0 -0
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/interpretation → interpretation}/collection.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/index.d.ts +0 -0
- /package/dist/{types/interpretation → interpretation}/siLanguage.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/controlsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/embeddedAppsUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/fullState.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/hostUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/infoUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/mediaSharesUtils.d.ts +0 -0
- /package/dist/{types/locus-info → locus-info}/selfUtils.d.ts +0 -0
- /package/dist/{types/media → media}/index.d.ts +0 -0
- /package/dist/{types/media → media}/properties.d.ts +0 -0
- /package/dist/{types/media → media}/util.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/muteState.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/request.type.d.ts +0 -0
- /package/dist/{types/meeting → meeting}/state.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/collection.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/request.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/util.d.ts +0 -0
- /package/dist/{types/meeting-info → meeting-info}/utilv2.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/meetings.types.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/request.d.ts +0 -0
- /package/dist/{types/meetings → meetings}/util.d.ts +0 -0
- /package/dist/{types/member → member}/types.d.ts +0 -0
- /package/dist/{types/member → member}/util.d.ts +0 -0
- /package/dist/{types/members → members}/collection.d.ts +0 -0
- /package/dist/{types/members → members}/index.d.ts +0 -0
- /package/dist/{types/members → members}/request.d.ts +0 -0
- /package/dist/{types/metrics → metrics}/index.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/mediaRequestManager.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlot.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/receiveSlotManager.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/remoteMedia.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/remoteMediaGroup.d.ts +0 -0
- /package/dist/{types/multistream → multistream}/sendSlotManager.d.ts +0 -0
- /package/dist/{types/networkQualityMonitor → networkQualityMonitor}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/index.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/request.d.ts +0 -0
- /package/dist/{types/personal-meeting-room → personal-meeting-room}/util.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/constants.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.d.ts +0 -0
- /package/dist/{types/reactions → reactions}/reactions.type.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/enums.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/index.d.ts +0 -0
- /package/dist/{types/recording-controller → recording-controller}/util.d.ts +0 -0
- /package/dist/{types/rtcMetrics → rtcMetrics}/constants.d.ts +0 -0
- /package/dist/{types/statsAnalyzer → statsAnalyzer}/global.d.ts +0 -0
- /package/dist/{types/transcription → transcription}/index.d.ts +0 -0
- /package/test/unit/spec/locus-info/{selfConstant.js → lib/selfConstant.js} +0 -0
|
@@ -3,20 +3,59 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/* eslint-disable class-methods-use-this */
|
|
6
|
-
|
|
7
|
-
import _ from 'lodash';
|
|
6
|
+
import {mapValues} from 'lodash';
|
|
8
7
|
|
|
9
8
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
10
9
|
import MeetingUtil from '../meeting/util';
|
|
11
10
|
|
|
12
|
-
import {
|
|
11
|
+
import {REACHABILITY} from '../constants';
|
|
12
|
+
|
|
13
|
+
import ReachabilityRequest, {ClusterList} from './request';
|
|
14
|
+
import {
|
|
15
|
+
ClusterReachability,
|
|
16
|
+
ClusterReachabilityResult,
|
|
17
|
+
TransportResult,
|
|
18
|
+
} from './clusterReachability';
|
|
19
|
+
|
|
20
|
+
export type ReachabilityMetrics = {
|
|
21
|
+
reachability_public_udp_success: number;
|
|
22
|
+
reachability_public_udp_failed: number;
|
|
23
|
+
reachability_public_tcp_success: number;
|
|
24
|
+
reachability_public_tcp_failed: number;
|
|
25
|
+
reachability_vmn_udp_success: number;
|
|
26
|
+
reachability_vmn_udp_failed: number;
|
|
27
|
+
reachability_vmn_tcp_success: number;
|
|
28
|
+
reachability_vmn_tcp_failed: number;
|
|
29
|
+
};
|
|
13
30
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
/**
|
|
32
|
+
* This is the type that matches what backend expects us to send to them. It is a bit weird, because
|
|
33
|
+
* it uses strings instead of booleans and numbers, but that's what they require.
|
|
34
|
+
*/
|
|
35
|
+
export type TransportResultForBackend = {
|
|
36
|
+
reachable?: 'true' | 'false';
|
|
37
|
+
latencyInMilliseconds?: string;
|
|
38
|
+
clientMediaIPs?: string[];
|
|
39
|
+
untested?: 'true';
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type ReachabilityResultForBackend = {
|
|
43
|
+
udp: TransportResultForBackend;
|
|
44
|
+
tcp: TransportResultForBackend;
|
|
45
|
+
xtls: TransportResultForBackend;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// this is the type that is required by the backend when we send them reachability results
|
|
49
|
+
export type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;
|
|
50
|
+
|
|
51
|
+
// this is the type used by Reachability class internally and stored in local storage
|
|
52
|
+
export type ReachabilityResults = Record<
|
|
53
|
+
string,
|
|
54
|
+
ClusterReachabilityResult & {
|
|
55
|
+
isVideoMesh?: boolean;
|
|
56
|
+
}
|
|
57
|
+
>;
|
|
18
58
|
|
|
19
|
-
export type ICECandidateResult = {clusterId: string; elapsed?: string | null; publicIPs?: string[]};
|
|
20
59
|
/**
|
|
21
60
|
* @class Reachability
|
|
22
61
|
* @export
|
|
@@ -24,8 +63,10 @@ export type ICECandidateResult = {clusterId: string; elapsed?: string | null; pu
|
|
|
24
63
|
export default class Reachability {
|
|
25
64
|
namespace = REACHABILITY.namespace;
|
|
26
65
|
webex: object;
|
|
27
|
-
reachabilityRequest:
|
|
28
|
-
|
|
66
|
+
reachabilityRequest: ReachabilityRequest;
|
|
67
|
+
clusterReachability: {
|
|
68
|
+
[key: string]: ClusterReachability;
|
|
69
|
+
};
|
|
29
70
|
|
|
30
71
|
/**
|
|
31
72
|
* Creates an instance of Reachability.
|
|
@@ -44,32 +85,16 @@ export default class Reachability {
|
|
|
44
85
|
*/
|
|
45
86
|
this.reachabilityRequest = new ReachabilityRequest(this.webex);
|
|
46
87
|
|
|
47
|
-
|
|
48
|
-
* internal object of clusters latency results
|
|
49
|
-
* @instance
|
|
50
|
-
* @type {object}
|
|
51
|
-
* @private
|
|
52
|
-
* @memberof Reachability
|
|
53
|
-
*/
|
|
54
|
-
this.clusterLatencyResults = {};
|
|
88
|
+
this.clusterReachability = {};
|
|
55
89
|
}
|
|
56
90
|
|
|
57
91
|
/**
|
|
58
|
-
*
|
|
59
|
-
* @returns {
|
|
92
|
+
* Gets a list of media clusters from the backend and performs reachability checks on all the clusters
|
|
93
|
+
* @returns {Promise<ReachabilityResults>} reachability results
|
|
60
94
|
* @public
|
|
61
|
-
* @async
|
|
62
95
|
* @memberof Reachability
|
|
63
96
|
*/
|
|
64
|
-
public async gatherReachability() {
|
|
65
|
-
this.setup();
|
|
66
|
-
|
|
67
|
-
// Remove stored reachability results to ensure no stale data
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageResult);
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageJoinCookie);
|
|
72
|
-
|
|
97
|
+
public async gatherReachability(): Promise<ReachabilityResults> {
|
|
73
98
|
// Fetch clusters and measure latency
|
|
74
99
|
try {
|
|
75
100
|
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
|
|
@@ -77,7 +102,7 @@ export default class Reachability {
|
|
|
77
102
|
);
|
|
78
103
|
|
|
79
104
|
// Perform Reachability Check
|
|
80
|
-
const results = await this.
|
|
105
|
+
const results = await this.performReachabilityChecks(clusters);
|
|
81
106
|
|
|
82
107
|
// @ts-ignore
|
|
83
108
|
await this.webex.boundedStorage.put(
|
|
@@ -97,145 +122,166 @@ export default class Reachability {
|
|
|
97
122
|
);
|
|
98
123
|
|
|
99
124
|
return results;
|
|
100
|
-
} catch (
|
|
101
|
-
LoggerProxy.logger.error(
|
|
102
|
-
`Reachability:index#gatherReachability --> Error in calling getClusters(): ${getClusterError}`
|
|
103
|
-
);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);
|
|
104
127
|
|
|
105
128
|
return {};
|
|
106
129
|
}
|
|
107
130
|
}
|
|
108
131
|
|
|
109
132
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* @
|
|
133
|
+
* Returns statistics about last reachability results. The returned value is an object
|
|
134
|
+
* with a flat list of properties so that it can be easily sent with metrics
|
|
135
|
+
*
|
|
136
|
+
* @returns {Promise} Promise with metrics values, it never rejects/throws.
|
|
114
137
|
*/
|
|
115
|
-
async
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
async getReachabilityMetrics(): Promise<ReachabilityMetrics> {
|
|
139
|
+
const stats: ReachabilityMetrics = {
|
|
140
|
+
reachability_public_udp_success: 0,
|
|
141
|
+
reachability_public_udp_failed: 0,
|
|
142
|
+
reachability_public_tcp_success: 0,
|
|
143
|
+
reachability_public_tcp_failed: 0,
|
|
144
|
+
reachability_vmn_udp_success: 0,
|
|
145
|
+
reachability_vmn_udp_failed: 0,
|
|
146
|
+
reachability_vmn_tcp_success: 0,
|
|
147
|
+
reachability_vmn_tcp_failed: 0,
|
|
148
|
+
};
|
|
125
149
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
LoggerProxy.logger.error(
|
|
131
|
-
`Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
|
|
132
|
-
);
|
|
150
|
+
const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {
|
|
151
|
+
if (result.udp && result.udp.result !== 'untested') {
|
|
152
|
+
const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';
|
|
153
|
+
stats[`reachability_${clusterType}_udp_${outcome}`] += 1;
|
|
133
154
|
}
|
|
155
|
+
if (result.tcp && result.tcp.result !== 'untested') {
|
|
156
|
+
const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';
|
|
157
|
+
stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
const resultsJson = await this.webex.boundedStorage.get(
|
|
164
|
+
REACHABILITY.namespace,
|
|
165
|
+
REACHABILITY.localStorageResult
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const results: ReachabilityResults = JSON.parse(resultsJson);
|
|
169
|
+
|
|
170
|
+
Object.values(results).forEach((result) => {
|
|
171
|
+
updateStats(result.isVideoMesh ? 'vmn' : 'public', result);
|
|
172
|
+
});
|
|
173
|
+
} catch (e) {
|
|
174
|
+
// empty storage, that's ok
|
|
175
|
+
LoggerProxy.logger.warn(
|
|
176
|
+
'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',
|
|
177
|
+
e
|
|
178
|
+
);
|
|
134
179
|
}
|
|
135
180
|
|
|
136
|
-
return
|
|
181
|
+
return stats;
|
|
137
182
|
}
|
|
138
183
|
|
|
139
184
|
/**
|
|
140
|
-
*
|
|
141
|
-
* @param {
|
|
142
|
-
* @returns {
|
|
143
|
-
* @private
|
|
144
|
-
* @memberof Reachability
|
|
185
|
+
* Maps our internal transport result to the format that backend expects
|
|
186
|
+
* @param {TransportResult} transportResult
|
|
187
|
+
* @returns {TransportResultForBackend}
|
|
145
188
|
*/
|
|
146
|
-
private
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
189
|
+
private mapTransportResultToBackendDataFormat(
|
|
190
|
+
transportResult: TransportResult
|
|
191
|
+
): TransportResultForBackend {
|
|
192
|
+
const output: TransportResultForBackend = {};
|
|
193
|
+
|
|
194
|
+
for (const [key, value] of Object.entries(transportResult)) {
|
|
195
|
+
switch (key) {
|
|
196
|
+
case 'result':
|
|
197
|
+
switch (value) {
|
|
198
|
+
case 'reachable':
|
|
199
|
+
output.reachable = 'true';
|
|
200
|
+
break;
|
|
201
|
+
case 'unreachable':
|
|
202
|
+
output.reachable = 'false';
|
|
203
|
+
break;
|
|
204
|
+
case 'untested':
|
|
205
|
+
output.untested = 'true';
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
case 'latencyInMilliseconds':
|
|
210
|
+
output.latencyInMilliseconds = value.toString();
|
|
211
|
+
break;
|
|
212
|
+
default:
|
|
213
|
+
output[key] = value;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return output;
|
|
158
218
|
}
|
|
159
219
|
|
|
160
220
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* @returns {
|
|
164
|
-
* @private
|
|
165
|
-
* @memberof Reachability
|
|
221
|
+
* Reachability results as an object in the format that backend expects
|
|
222
|
+
*
|
|
223
|
+
* @returns {any} reachability results that need to be sent to the backend
|
|
166
224
|
*/
|
|
167
|
-
|
|
168
|
-
|
|
225
|
+
async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {
|
|
226
|
+
let results: ReachabilityResultsForBackend;
|
|
169
227
|
|
|
170
228
|
try {
|
|
171
|
-
const peerConnection = new window.RTCPeerConnection(config);
|
|
172
|
-
|
|
173
229
|
// @ts-ignore
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
} catch (peerConnectionError) {
|
|
178
|
-
LoggerProxy.logger.log(
|
|
179
|
-
`Reachability:index#createPeerConnection --> Error creating peerConnection: ${peerConnectionError}`
|
|
230
|
+
const resultsJson = await this.webex.boundedStorage.get(
|
|
231
|
+
REACHABILITY.namespace,
|
|
232
|
+
REACHABILITY.localStorageResult
|
|
180
233
|
);
|
|
181
234
|
|
|
182
|
-
|
|
235
|
+
const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);
|
|
236
|
+
|
|
237
|
+
results = mapValues(allClusterResults, (clusterResult) => ({
|
|
238
|
+
udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),
|
|
239
|
+
tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),
|
|
240
|
+
xtls: this.mapTransportResultToBackendDataFormat(
|
|
241
|
+
clusterResult.xtls || {result: 'untested'}
|
|
242
|
+
),
|
|
243
|
+
}));
|
|
244
|
+
} catch (e) {
|
|
245
|
+
// empty storage, that's ok
|
|
246
|
+
LoggerProxy.logger.warn(
|
|
247
|
+
'Roap:request#attachReachabilityData --> Error parsing reachability data: ',
|
|
248
|
+
e
|
|
249
|
+
);
|
|
183
250
|
}
|
|
184
|
-
}
|
|
185
251
|
|
|
186
|
-
|
|
187
|
-
* Gets total elapsed time
|
|
188
|
-
* @param {RTCPeerConnection} peerConnection
|
|
189
|
-
* @returns {Number} Milliseconds
|
|
190
|
-
* @private
|
|
191
|
-
* @memberof Reachability
|
|
192
|
-
*/
|
|
193
|
-
private getElapsedTime(peerConnection: any) {
|
|
194
|
-
const startTime = peerConnection.begin;
|
|
195
|
-
|
|
196
|
-
delete peerConnection.begin;
|
|
197
|
-
|
|
198
|
-
return Date.now() - startTime;
|
|
252
|
+
return results;
|
|
199
253
|
}
|
|
200
254
|
|
|
201
255
|
/**
|
|
202
|
-
*
|
|
203
|
-
* @
|
|
204
|
-
* @
|
|
205
|
-
* @private
|
|
256
|
+
* fetches reachability data and checks for cluster reachability
|
|
257
|
+
* @returns {boolean}
|
|
258
|
+
* @public
|
|
206
259
|
* @memberof Reachability
|
|
207
260
|
*/
|
|
208
|
-
|
|
209
|
-
let
|
|
261
|
+
async isAnyPublicClusterReachable() {
|
|
262
|
+
let reachable = false;
|
|
263
|
+
// @ts-ignore
|
|
264
|
+
const reachabilityData = await this.webex.boundedStorage
|
|
265
|
+
.get(this.namespace, REACHABILITY.localStorageResult)
|
|
266
|
+
.catch(() => {});
|
|
210
267
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const peerConnection = this.createPeerConnection({key, config});
|
|
215
|
-
const description = await peerConnection.createOffer({offerToReceiveAudio: true});
|
|
268
|
+
if (reachabilityData) {
|
|
269
|
+
try {
|
|
270
|
+
const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);
|
|
216
271
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return this.iceGatheringState(
|
|
222
|
-
peerConnection,
|
|
223
|
-
cluster.isVideoMesh ? VIDEO_MESH_TIMEOUT : DEFAULT_TIMEOUT
|
|
224
|
-
).catch((iceGatheringStateError) => {
|
|
225
|
-
LoggerProxy.logger.log(
|
|
226
|
-
`Reachability:index#getLocalSDPForClusters --> Error in getLocalSDP : ${iceGatheringStateError}`
|
|
272
|
+
reachable = Object.values(reachabilityResults).some(
|
|
273
|
+
(result) =>
|
|
274
|
+
!result.isVideoMesh &&
|
|
275
|
+
(result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')
|
|
227
276
|
);
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this.logUnreachableClusters();
|
|
277
|
+
} catch (e) {
|
|
278
|
+
LoggerProxy.logger.error(
|
|
279
|
+
`Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
235
283
|
|
|
236
|
-
|
|
237
|
-
return reachabilityLatencyResults;
|
|
238
|
-
});
|
|
284
|
+
return reachable;
|
|
239
285
|
}
|
|
240
286
|
|
|
241
287
|
/**
|
|
@@ -244,131 +290,23 @@ export default class Reachability {
|
|
|
244
290
|
* @private
|
|
245
291
|
* @memberof Reachability
|
|
246
292
|
*/
|
|
247
|
-
private
|
|
293
|
+
private getUnreachableClusters(): Array<{name: string; protocol: string}> {
|
|
248
294
|
const unreachableList = [];
|
|
249
|
-
const clusters = this.clusterLatencyResults;
|
|
250
295
|
|
|
251
|
-
Object.
|
|
252
|
-
const
|
|
296
|
+
Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {
|
|
297
|
+
const result = clusterReachability.getResult();
|
|
253
298
|
|
|
254
|
-
if (
|
|
255
|
-
unreachableList.push(key);
|
|
299
|
+
if (result.udp.result === 'unreachable') {
|
|
300
|
+
unreachableList.push({name: key, protocol: 'udp'});
|
|
301
|
+
}
|
|
302
|
+
if (result.tcp.result === 'unreachable') {
|
|
303
|
+
unreachableList.push({name: key, protocol: 'tcp'});
|
|
256
304
|
}
|
|
257
305
|
});
|
|
258
306
|
|
|
259
307
|
return unreachableList;
|
|
260
308
|
}
|
|
261
309
|
|
|
262
|
-
/**
|
|
263
|
-
* Attach an event handler for the icegatheringstatechange
|
|
264
|
-
* event and measure latency.
|
|
265
|
-
* @param {RTCPeerConnection} peerConnection
|
|
266
|
-
* @returns {undefined}
|
|
267
|
-
* @private
|
|
268
|
-
* @memberof Reachability
|
|
269
|
-
*/
|
|
270
|
-
private handleIceGatheringStateChange(peerConnection: RTCPeerConnection) {
|
|
271
|
-
peerConnection.onicegatheringstatechange = () => {
|
|
272
|
-
const {COMPLETE} = ICE_GATHERING_STATE;
|
|
273
|
-
|
|
274
|
-
if (peerConnection.iceConnectionState === COMPLETE) {
|
|
275
|
-
const elapsed = this.getElapsedTime(peerConnection);
|
|
276
|
-
|
|
277
|
-
// @ts-ignore
|
|
278
|
-
LoggerProxy.logger.log(
|
|
279
|
-
// @ts-ignore
|
|
280
|
-
`Reachability:index#onIceGatheringStateChange --> Successfully pinged ${peerConnection.key}:`,
|
|
281
|
-
elapsed
|
|
282
|
-
);
|
|
283
|
-
this.setLatencyAndClose(peerConnection, elapsed);
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Attach an event handler for the icecandidate
|
|
290
|
-
* event and measure latency.
|
|
291
|
-
* @param {RTCPeerConnection} peerConnection
|
|
292
|
-
* @returns {undefined}
|
|
293
|
-
* @private
|
|
294
|
-
* @memberof Reachability
|
|
295
|
-
*/
|
|
296
|
-
private handleOnIceCandidate(peerConnection: RTCPeerConnection) {
|
|
297
|
-
peerConnection.onicecandidate = (e) => {
|
|
298
|
-
const SERVER_REFLEXIVE = 'srflx';
|
|
299
|
-
|
|
300
|
-
if (e.candidate && String(e.candidate.type).toLowerCase() === SERVER_REFLEXIVE) {
|
|
301
|
-
const elapsed = this.getElapsedTime(peerConnection);
|
|
302
|
-
|
|
303
|
-
LoggerProxy.logger.log(
|
|
304
|
-
// @ts-ignore
|
|
305
|
-
`Reachability:index#onIceCandidate --> Successfully pinged ${peerConnection.key}:`,
|
|
306
|
-
elapsed
|
|
307
|
-
);
|
|
308
|
-
// order is important
|
|
309
|
-
this.addPublicIP(peerConnection, e.candidate.address);
|
|
310
|
-
this.setLatencyAndClose(peerConnection, elapsed);
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* An event handler on an RTCPeerConnection when the state of the ICE
|
|
317
|
-
* candidate gathering process changes. Used to measure connection
|
|
318
|
-
* speed.
|
|
319
|
-
* @private
|
|
320
|
-
* @param {RTCPeerConnection} peerConnection
|
|
321
|
-
* @param {number} timeout
|
|
322
|
-
* @returns {Promise}
|
|
323
|
-
*/
|
|
324
|
-
private iceGatheringState(peerConnection: RTCPeerConnection, timeout: number) {
|
|
325
|
-
const ELAPSED = 'elapsed';
|
|
326
|
-
|
|
327
|
-
return new Promise<ICECandidateResult>((resolve) => {
|
|
328
|
-
const peerConnectionProxy = new window.Proxy(peerConnection, {
|
|
329
|
-
// eslint-disable-next-line require-jsdoc
|
|
330
|
-
get(target, property) {
|
|
331
|
-
const targetMember = target[property];
|
|
332
|
-
|
|
333
|
-
if (typeof targetMember === 'function') {
|
|
334
|
-
return targetMember.bind(target);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
return targetMember;
|
|
338
|
-
},
|
|
339
|
-
set: (target, property, value) => {
|
|
340
|
-
// only intercept elapsed property
|
|
341
|
-
if (property === ELAPSED) {
|
|
342
|
-
// @ts-ignore
|
|
343
|
-
resolve({clusterId: peerConnection.key, publicIPs: target.publicIPs, elapsed: value});
|
|
344
|
-
|
|
345
|
-
return true;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// pass thru
|
|
349
|
-
return window.Reflect.set(target, property, value);
|
|
350
|
-
},
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// Using peerConnection proxy so handle functions below
|
|
354
|
-
// won't be coupled to our promise implementation
|
|
355
|
-
this.handleIceGatheringStateChange(peerConnectionProxy);
|
|
356
|
-
this.handleOnIceCandidate(peerConnectionProxy);
|
|
357
|
-
|
|
358
|
-
// Set maximum timeout
|
|
359
|
-
window.setTimeout(() => {
|
|
360
|
-
const {CLOSED} = CONNECTION_STATE;
|
|
361
|
-
|
|
362
|
-
// Close any open peerConnections
|
|
363
|
-
if (peerConnectionProxy.connectionState !== CLOSED) {
|
|
364
|
-
// order is important
|
|
365
|
-
this.addPublicIP(peerConnectionProxy, null);
|
|
366
|
-
this.setLatencyAndClose(peerConnectionProxy, null);
|
|
367
|
-
}
|
|
368
|
-
}, timeout);
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
|
|
372
310
|
/**
|
|
373
311
|
* Make a log of unreachable clusters.
|
|
374
312
|
* @returns {undefined}
|
|
@@ -376,157 +314,58 @@ export default class Reachability {
|
|
|
376
314
|
* @memberof Reachability
|
|
377
315
|
*/
|
|
378
316
|
private logUnreachableClusters() {
|
|
379
|
-
const list = this.
|
|
317
|
+
const list = this.getUnreachableClusters();
|
|
380
318
|
|
|
381
|
-
list.forEach((
|
|
319
|
+
list.forEach(({name, protocol}) => {
|
|
382
320
|
LoggerProxy.logger.log(
|
|
383
|
-
`Reachability:index#logUnreachableClusters -->
|
|
321
|
+
`Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`
|
|
384
322
|
);
|
|
385
323
|
});
|
|
386
324
|
}
|
|
387
325
|
|
|
388
326
|
/**
|
|
389
|
-
*
|
|
390
|
-
* @param {
|
|
391
|
-
* @returns {
|
|
392
|
-
* @protected
|
|
393
|
-
* @memberof Reachability
|
|
327
|
+
* Performs reachability checks for all clusters
|
|
328
|
+
* @param {ClusterList} clusterList
|
|
329
|
+
* @returns {Promise<ReachabilityResults>} reachability check results
|
|
394
330
|
*/
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
iceResults.forEach(({clusterId, elapsed, publicIPs}) => {
|
|
399
|
-
const latencyResult = {};
|
|
400
|
-
|
|
401
|
-
if (!elapsed) {
|
|
402
|
-
Object.assign(latencyResult, {reachable: 'false'});
|
|
403
|
-
} else {
|
|
404
|
-
Object.assign(latencyResult, {
|
|
405
|
-
reachable: 'true',
|
|
406
|
-
latencyInMilliseconds: elapsed.toString(),
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (publicIPs) {
|
|
411
|
-
Object.assign(latencyResult, {
|
|
412
|
-
clientMediaIPs: publicIPs,
|
|
413
|
-
});
|
|
414
|
-
}
|
|
331
|
+
private async performReachabilityChecks(clusterList: ClusterList): Promise<ReachabilityResults> {
|
|
332
|
+
const results: ReachabilityResults = {};
|
|
415
333
|
|
|
416
|
-
reachabilityMap[clusterId] = {
|
|
417
|
-
udp: latencyResult,
|
|
418
|
-
tcp: {untested: 'true'},
|
|
419
|
-
xtls: {untested: 'true'},
|
|
420
|
-
};
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
return reachabilityMap;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* fetches reachability data
|
|
428
|
-
* @param {object} clusterList
|
|
429
|
-
* @returns {Promise<localSDPData>} reachability check results
|
|
430
|
-
* @private
|
|
431
|
-
* @memberof Reachability
|
|
432
|
-
*/
|
|
433
|
-
private performReachabilityCheck(clusterList: object) {
|
|
434
334
|
if (!clusterList || !Object.keys(clusterList).length) {
|
|
435
|
-
return Promise.resolve(
|
|
335
|
+
return Promise.resolve(results);
|
|
436
336
|
}
|
|
437
337
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
'Reachability:index#performReachabilityCheck --> Local SDP is empty or has missing elements..returning'
|
|
445
|
-
);
|
|
446
|
-
resolve({});
|
|
447
|
-
} else {
|
|
448
|
-
resolve(localSDPData);
|
|
449
|
-
}
|
|
450
|
-
})
|
|
451
|
-
.catch((error) => {
|
|
452
|
-
LoggerProxy.logger.error(
|
|
453
|
-
`Reachability:index#performReachabilityCheck --> Error in getLocalSDPForClusters: ${error}`
|
|
454
|
-
);
|
|
455
|
-
resolve({});
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
}
|
|
338
|
+
LoggerProxy.logger.log(
|
|
339
|
+
`Reachability:index#performReachabilityChecks --> doing UDP${
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
this.webex.config.meetings.experimental.enableTcpReachability ? ' and TCP' : ''
|
|
342
|
+
} reachability checks`
|
|
343
|
+
);
|
|
459
344
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
* @param {RTCPeerConnection} peerConnection
|
|
463
|
-
* @param {string} publicIP
|
|
464
|
-
* @returns {void}
|
|
465
|
-
*/
|
|
466
|
-
protected addPublicIP(peerConnection: RTCPeerConnection, publicIP?: string | null) {
|
|
467
|
-
const modifiedPeerConnection: RTCPeerConnection & {publicIPs?: string[]} = peerConnection;
|
|
468
|
-
const {CLOSED} = CONNECTION_STATE;
|
|
345
|
+
const clusterReachabilityChecks = Object.keys(clusterList).map((key) => {
|
|
346
|
+
const cluster = clusterList[key];
|
|
469
347
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
348
|
+
// Linus doesn't support TCP reachability checks on video mesh nodes
|
|
349
|
+
const includeTcpReachability =
|
|
350
|
+
// @ts-ignore
|
|
351
|
+
this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;
|
|
475
352
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
modifiedPeerConnection.publicIPs.push(publicIP);
|
|
479
|
-
} else {
|
|
480
|
-
modifiedPeerConnection.publicIPs = [publicIP];
|
|
353
|
+
if (!includeTcpReachability) {
|
|
354
|
+
cluster.tcp = [];
|
|
481
355
|
}
|
|
482
|
-
} else {
|
|
483
|
-
modifiedPeerConnection.publicIPs = null;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
356
|
|
|
487
|
-
|
|
488
|
-
* Records latency and closes the peerConnection
|
|
489
|
-
* @param {RTCPeerConnection} peerConnection
|
|
490
|
-
* @param {number} elapsed Latency in milliseconds
|
|
491
|
-
* @returns {undefined}
|
|
492
|
-
* @private
|
|
493
|
-
* @memberof Reachability
|
|
494
|
-
*/
|
|
495
|
-
private setLatencyAndClose(peerConnection: RTCPeerConnection, elapsed: number) {
|
|
496
|
-
const REACHABLE = 'reachable';
|
|
497
|
-
const UNREACHABLE = 'unreachable';
|
|
498
|
-
const {CLOSED} = CONNECTION_STATE;
|
|
499
|
-
// @ts-ignore
|
|
500
|
-
const {key} = peerConnection;
|
|
501
|
-
const resultKey = elapsed === null ? UNREACHABLE : REACHABLE;
|
|
502
|
-
const intialState = {[REACHABLE]: 0, [UNREACHABLE]: 0};
|
|
503
|
-
|
|
504
|
-
if (peerConnection.connectionState === CLOSED) {
|
|
505
|
-
LoggerProxy.logger.log(
|
|
506
|
-
`Reachability:index#setLatencyAndClose --> Attempting to set latency of ${elapsed} on closed peerConnection.`
|
|
507
|
-
);
|
|
357
|
+
this.clusterReachability[key] = new ClusterReachability(key, cluster);
|
|
508
358
|
|
|
509
|
-
return
|
|
510
|
-
|
|
359
|
+
return this.clusterReachability[key].start().then((result) => {
|
|
360
|
+
results[key] = result;
|
|
361
|
+
results[key].isVideoMesh = cluster.isVideoMesh;
|
|
362
|
+
});
|
|
363
|
+
});
|
|
511
364
|
|
|
512
|
-
|
|
513
|
-
this.clusterLatencyResults[key][resultKey] += 1;
|
|
365
|
+
await Promise.all(clusterReachabilityChecks);
|
|
514
366
|
|
|
515
|
-
|
|
516
|
-
// an event other than onIceCandidate
|
|
517
|
-
peerConnection.onicecandidate = null;
|
|
518
|
-
peerConnection.close();
|
|
519
|
-
// @ts-ignore
|
|
520
|
-
peerConnection.elapsed = elapsed;
|
|
521
|
-
}
|
|
367
|
+
this.logUnreachableClusters();
|
|
522
368
|
|
|
523
|
-
|
|
524
|
-
* utility function
|
|
525
|
-
* @returns {undefined}
|
|
526
|
-
* @private
|
|
527
|
-
* @memberof Reachability
|
|
528
|
-
*/
|
|
529
|
-
private setup() {
|
|
530
|
-
this.clusterLatencyResults = {};
|
|
369
|
+
return results;
|
|
531
370
|
}
|
|
532
371
|
}
|