@webex/plugin-meetings 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +7 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +11 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/selfUtils.js +0 -5
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +70 -15
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +12 -0
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +552 -357
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +7 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +6 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +4 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +17 -17
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +16 -16
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +1 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +37 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +8 -0
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/util.js +3 -2
- package/dist/meetings/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +57 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +1 -1
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/reachability/clusterReachability.js +108 -53
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +415 -56
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +11 -3
- package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +27 -7
- package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
- package/dist/types/meeting-info/index.d.ts +3 -2
- package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
- package/dist/types/meeting-info/util.d.ts +5 -4
- package/dist/types/meeting-info/utilv2.d.ts +3 -2
- package/dist/types/meetings/collection.d.ts +3 -2
- package/dist/types/meetings/index.d.ts +4 -3
- package/dist/types/meetings/meetings.types.d.ts +9 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +15 -0
- package/dist/types/reachability/clusterReachability.d.ts +31 -3
- package/dist/types/reachability/index.d.ts +93 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +23 -23
- package/src/breakouts/index.ts +7 -1
- package/src/constants.ts +13 -17
- package/src/locus-info/selfUtils.ts +0 -5
- package/src/media/MediaConnectionAwaiter.ts +89 -14
- package/src/media/index.ts +13 -0
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +526 -292
- package/src/meeting/locusMediaRequest.ts +5 -0
- package/src/meeting/muteState.ts +6 -1
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/index.ts +9 -6
- package/src/meeting-info/meeting-info-v2.ts +4 -4
- package/src/meeting-info/util.ts +23 -28
- package/src/meeting-info/utilv2.ts +18 -24
- package/src/meetings/collection.ts +3 -3
- package/src/meetings/index.ts +39 -40
- package/src/meetings/meetings.types.ts +11 -0
- package/src/meetings/util.ts +5 -4
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +44 -0
- package/src/personal-meeting-room/index.ts +2 -2
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +316 -27
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/locus-info/selfUtils.js +25 -23
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
- package/test/unit/spec/media/index.ts +42 -27
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +758 -179
- package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
- package/test/unit/spec/meeting/muteState.js +24 -0
- package/test/unit/spec/meeting-info/index.js +4 -4
- package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
- package/test/unit/spec/meeting-info/request.js +2 -2
- package/test/unit/spec/meeting-info/utilv2.js +41 -49
- package/test/unit/spec/meetings/index.js +14 -0
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1153 -84
- package/test/unit/spec/rtcMetrics/index.ts +1 -0
- package/dist/mediaQualityMetrics/config.js +0 -321
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/statsAnalyzer/global.js +0 -44
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.js +0 -1072
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.js +0 -368
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
- package/dist/types/statsAnalyzer/global.d.ts +0 -36
- package/dist/types/statsAnalyzer/index.d.ts +0 -217
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
- package/src/mediaQualityMetrics/config.ts +0 -255
- package/src/statsAnalyzer/global.ts +0 -37
- package/src/statsAnalyzer/index.ts +0 -1318
- package/src/statsAnalyzer/mqaUtil.ts +0 -463
- package/test/unit/spec/stats-analyzer/index.js +0 -1819
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ClusterNode } from './request';
|
|
2
|
+
import EventsScope from '../common/events/events-scope';
|
|
3
|
+
import { Enum } from '../constants';
|
|
2
4
|
export type TransportResult = {
|
|
3
5
|
result: 'reachable' | 'unreachable' | 'untested';
|
|
4
6
|
latencyInMilliseconds?: number;
|
|
@@ -9,10 +11,26 @@ export type ClusterReachabilityResult = {
|
|
|
9
11
|
tcp: TransportResult;
|
|
10
12
|
xtls: TransportResult;
|
|
11
13
|
};
|
|
14
|
+
export type ResultEventData = {
|
|
15
|
+
protocol: 'udp' | 'tcp' | 'xtls';
|
|
16
|
+
result: 'reachable' | 'unreachable' | 'untested';
|
|
17
|
+
latencyInMilliseconds: number;
|
|
18
|
+
clientMediaIPs?: string[];
|
|
19
|
+
};
|
|
20
|
+
export type ClientMediaIpsUpdatedEventData = {
|
|
21
|
+
protocol: 'udp' | 'tcp' | 'xtls';
|
|
22
|
+
clientMediaIPs: string[];
|
|
23
|
+
};
|
|
24
|
+
export declare const Events: {
|
|
25
|
+
readonly resultReady: "resultReady";
|
|
26
|
+
readonly clientMediaIpsUpdated: "clientMediaIpsUpdated";
|
|
27
|
+
};
|
|
28
|
+
export type Events = Enum<typeof Events>;
|
|
12
29
|
/**
|
|
13
30
|
* A class that handles reachability checks for a single cluster.
|
|
31
|
+
* It emits events from Events enum
|
|
14
32
|
*/
|
|
15
|
-
export declare class ClusterReachability {
|
|
33
|
+
export declare class ClusterReachability extends EventsScope {
|
|
16
34
|
private numUdpUrls;
|
|
17
35
|
private numTcpUrls;
|
|
18
36
|
private numXTlsUrls;
|
|
@@ -61,6 +79,12 @@ export declare class ClusterReachability {
|
|
|
61
79
|
* @returns {void}
|
|
62
80
|
*/
|
|
63
81
|
private finishReachabilityCheck;
|
|
82
|
+
/**
|
|
83
|
+
* Aborts the cluster reachability checks by closing the peer connection
|
|
84
|
+
*
|
|
85
|
+
* @returns {void}
|
|
86
|
+
*/
|
|
87
|
+
abort(): void;
|
|
64
88
|
/**
|
|
65
89
|
* Adds public IP (client media IPs)
|
|
66
90
|
* @param {string} protocol
|
|
@@ -81,13 +105,17 @@ export declare class ClusterReachability {
|
|
|
81
105
|
*/
|
|
82
106
|
private haveWeGotAllResults;
|
|
83
107
|
/**
|
|
84
|
-
*
|
|
108
|
+
* Saves the latency in the result for the given protocol and marks it as reachable,
|
|
109
|
+
* emits the "resultReady" event if this is the first result for that protocol,
|
|
110
|
+
* emits the "clientMediaIpsUpdated" event if we already had a result and only found
|
|
111
|
+
* a new client IP
|
|
85
112
|
*
|
|
86
113
|
* @param {string} protocol
|
|
87
114
|
* @param {number} latency
|
|
115
|
+
* @param {string|null} [publicIp]
|
|
88
116
|
* @returns {void}
|
|
89
117
|
*/
|
|
90
|
-
private
|
|
118
|
+
private saveResult;
|
|
91
119
|
/**
|
|
92
120
|
* Registers a listener for the icecandidate event
|
|
93
121
|
*
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
|
+
import { Defer } from '@webex/common';
|
|
4
5
|
import ReachabilityRequest from './request';
|
|
5
6
|
import { ClusterReachability, ClusterReachabilityResult } from './clusterReachability';
|
|
7
|
+
import EventsScope from '../common/events/events-scope';
|
|
6
8
|
export type ReachabilityMetrics = {
|
|
7
9
|
reachability_public_udp_success: number;
|
|
8
10
|
reachability_public_udp_failed: number;
|
|
@@ -40,13 +42,37 @@ export type ReachabilityResults = Record<string, ClusterReachabilityResult & {
|
|
|
40
42
|
* @class Reachability
|
|
41
43
|
* @export
|
|
42
44
|
*/
|
|
43
|
-
export default class Reachability {
|
|
45
|
+
export default class Reachability extends EventsScope {
|
|
44
46
|
namespace: string;
|
|
45
47
|
webex: object;
|
|
46
48
|
reachabilityRequest: ReachabilityRequest;
|
|
47
49
|
clusterReachability: {
|
|
48
50
|
[key: string]: ClusterReachability;
|
|
49
51
|
};
|
|
52
|
+
reachabilityDefer?: Defer;
|
|
53
|
+
vmnTimer?: ReturnType<typeof setTimeout>;
|
|
54
|
+
publicCloudTimer?: ReturnType<typeof setTimeout>;
|
|
55
|
+
overallTimer?: ReturnType<typeof setTimeout>;
|
|
56
|
+
expectedResultsCount: {
|
|
57
|
+
videoMesh: {
|
|
58
|
+
udp: number;
|
|
59
|
+
};
|
|
60
|
+
public: {
|
|
61
|
+
udp: number;
|
|
62
|
+
tcp: number;
|
|
63
|
+
xtls: number;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
resultsCount: {
|
|
67
|
+
videoMesh: {
|
|
68
|
+
udp: number;
|
|
69
|
+
};
|
|
70
|
+
public: {
|
|
71
|
+
udp: number;
|
|
72
|
+
tcp: number;
|
|
73
|
+
xtls: number;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
50
76
|
/**
|
|
51
77
|
* Creates an instance of Reachability.
|
|
52
78
|
* @param {object} webex
|
|
@@ -111,10 +137,75 @@ export default class Reachability {
|
|
|
111
137
|
* @memberof Reachability
|
|
112
138
|
*/
|
|
113
139
|
private logUnreachableClusters;
|
|
140
|
+
/**
|
|
141
|
+
* Returns true if we've obtained all the reachability results for all the public clusters
|
|
142
|
+
* In other words, it means that all public clusters are reachable over each protocol,
|
|
143
|
+
* because we only get a "result" if we managed to reach a cluster
|
|
144
|
+
*
|
|
145
|
+
* @returns {boolean}
|
|
146
|
+
*/
|
|
147
|
+
private areAllPublicClusterResultsReady;
|
|
148
|
+
/**
|
|
149
|
+
* Returns true if we've obtained all the reachability results for all the clusters
|
|
150
|
+
*
|
|
151
|
+
* @returns {boolean}
|
|
152
|
+
*/
|
|
153
|
+
private areAllResultsReady;
|
|
154
|
+
/**
|
|
155
|
+
* Resolves the promise returned by gatherReachability() method
|
|
156
|
+
* @returns {void}
|
|
157
|
+
*/
|
|
158
|
+
private resolveReachabilityPromise;
|
|
159
|
+
/**
|
|
160
|
+
* Aborts all cluster reachability checks that are in progress
|
|
161
|
+
*
|
|
162
|
+
* @returns {void}
|
|
163
|
+
*/
|
|
164
|
+
private abortClusterReachability;
|
|
165
|
+
/**
|
|
166
|
+
* Helper function for calculating min/max/average values of latency
|
|
167
|
+
*
|
|
168
|
+
* @param {Array<any>} results
|
|
169
|
+
* @param {string} protocol
|
|
170
|
+
* @param {boolean} isVideoMesh
|
|
171
|
+
* @returns {{min:number, max: number, average: number}}
|
|
172
|
+
*/
|
|
173
|
+
protected getStatistics(results: Array<ClusterReachabilityResult & {
|
|
174
|
+
isVideoMesh: boolean;
|
|
175
|
+
}>, protocol: 'udp' | 'tcp' | 'xtls', isVideoMesh: boolean): {
|
|
176
|
+
min: number;
|
|
177
|
+
max: number;
|
|
178
|
+
average: number;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Sends a metric with all the statistics about how long reachability took
|
|
182
|
+
*
|
|
183
|
+
* @returns {void}
|
|
184
|
+
*/
|
|
185
|
+
protected sendMetric(): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Starts all the timers used for various timeouts
|
|
188
|
+
*
|
|
189
|
+
* @returns {void}
|
|
190
|
+
*/
|
|
191
|
+
private startTimers;
|
|
192
|
+
/**
|
|
193
|
+
* Stores given reachability results in local storage
|
|
194
|
+
*
|
|
195
|
+
* @param {ReachabilityResults} results
|
|
196
|
+
* @returns {Promise<void>}
|
|
197
|
+
*/
|
|
198
|
+
private storeResults;
|
|
199
|
+
/**
|
|
200
|
+
* Resets all the internal counters that keep track of the results
|
|
201
|
+
*
|
|
202
|
+
* @returns {void}
|
|
203
|
+
*/
|
|
204
|
+
private resetResultCounters;
|
|
114
205
|
/**
|
|
115
206
|
* Performs reachability checks for all clusters
|
|
116
207
|
* @param {ClusterList} clusterList
|
|
117
|
-
* @returns {Promise<
|
|
208
|
+
* @returns {Promise<void>} promise that's resolved as soon as the checks are started
|
|
118
209
|
*/
|
|
119
210
|
private performReachabilityChecks;
|
|
120
211
|
}
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.
|
|
65
|
+
version: "3.4.0"
|
|
66
66
|
});
|
|
67
67
|
var _default = exports.default = Webinar;
|
|
68
68
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.
|
|
47
|
-
"@webex/plugin-rooms": "3.
|
|
48
|
-
"@webex/test-helper-chai": "3.
|
|
49
|
-
"@webex/test-helper-mocha": "3.
|
|
50
|
-
"@webex/test-helper-mock-webex": "3.
|
|
51
|
-
"@webex/test-helper-retry": "3.
|
|
52
|
-
"@webex/test-helper-test-users": "3.
|
|
46
|
+
"@webex/plugin-meetings": "3.4.0",
|
|
47
|
+
"@webex/plugin-rooms": "3.4.0",
|
|
48
|
+
"@webex/test-helper-chai": "3.4.0",
|
|
49
|
+
"@webex/test-helper-mocha": "3.4.0",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.4.0",
|
|
51
|
+
"@webex/test-helper-retry": "3.4.0",
|
|
52
|
+
"@webex/test-helper-test-users": "3.4.0",
|
|
53
53
|
"chai": "^4.3.4",
|
|
54
54
|
"chai-as-promised": "^7.1.1",
|
|
55
55
|
"eslint": "^8.24.0",
|
|
@@ -61,20 +61,21 @@
|
|
|
61
61
|
"typescript": "^4.7.4"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@webex/common": "3.
|
|
65
|
-
"@webex/internal-media-core": "2.
|
|
66
|
-
"@webex/internal-plugin-conversation": "3.
|
|
67
|
-
"@webex/internal-plugin-device": "3.
|
|
68
|
-
"@webex/internal-plugin-llm": "3.
|
|
69
|
-
"@webex/internal-plugin-mercury": "3.
|
|
70
|
-
"@webex/internal-plugin-metrics": "3.
|
|
71
|
-
"@webex/internal-plugin-support": "3.
|
|
72
|
-
"@webex/internal-plugin-user": "3.
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.
|
|
74
|
-
"@webex/media-helpers": "3.
|
|
75
|
-
"@webex/plugin-people": "3.
|
|
76
|
-
"@webex/plugin-rooms": "3.
|
|
77
|
-
"@webex/
|
|
64
|
+
"@webex/common": "3.4.0",
|
|
65
|
+
"@webex/internal-media-core": "2.10.0",
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.4.0",
|
|
67
|
+
"@webex/internal-plugin-device": "3.4.0",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.4.0",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.4.0",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.4.0",
|
|
71
|
+
"@webex/internal-plugin-support": "3.4.0",
|
|
72
|
+
"@webex/internal-plugin-user": "3.4.0",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.4.0",
|
|
74
|
+
"@webex/media-helpers": "3.4.0",
|
|
75
|
+
"@webex/plugin-people": "3.4.0",
|
|
76
|
+
"@webex/plugin-rooms": "3.4.0",
|
|
77
|
+
"@webex/web-capabilities": "^1.4.0",
|
|
78
|
+
"@webex/webex-core": "3.4.0",
|
|
78
79
|
"ampersand-collection": "^2.0.2",
|
|
79
80
|
"bowser": "^2.11.0",
|
|
80
81
|
"btoa": "^1.2.1",
|
|
@@ -84,12 +85,11 @@
|
|
|
84
85
|
"javascript-state-machine": "^3.1.0",
|
|
85
86
|
"jwt-decode": "3.1.2",
|
|
86
87
|
"lodash": "^4.17.21",
|
|
87
|
-
"sdp-transform": "^2.12.0",
|
|
88
88
|
"uuid": "^3.3.2",
|
|
89
89
|
"webrtc-adapter": "^8.1.2"
|
|
90
90
|
},
|
|
91
91
|
"//": [
|
|
92
92
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
93
93
|
],
|
|
94
|
-
"version": "3.
|
|
94
|
+
"version": "3.4.0"
|
|
95
95
|
}
|
package/src/breakouts/index.ts
CHANGED
|
@@ -148,7 +148,6 @@ const Breakouts = WebexPlugin.extend({
|
|
|
148
148
|
this.triggerReturnToMainEvent(breakout);
|
|
149
149
|
});
|
|
150
150
|
this.listenToCurrentSessionTypeChange();
|
|
151
|
-
this.listenToBroadcastMessages();
|
|
152
151
|
this.listenToBreakoutRosters();
|
|
153
152
|
this.listenToBreakoutHelp();
|
|
154
153
|
// @ts-ignore
|
|
@@ -161,6 +160,7 @@ const Breakouts = WebexPlugin.extend({
|
|
|
161
160
|
*/
|
|
162
161
|
cleanUp() {
|
|
163
162
|
this.stopListening();
|
|
163
|
+
this.hasSubscribedToMessage = undefined;
|
|
164
164
|
},
|
|
165
165
|
|
|
166
166
|
/**
|
|
@@ -170,6 +170,7 @@ const Breakouts = WebexPlugin.extend({
|
|
|
170
170
|
*/
|
|
171
171
|
locusUrlUpdate(locusUrl) {
|
|
172
172
|
this.set('locusUrl', locusUrl);
|
|
173
|
+
this.listenToBroadcastMessages();
|
|
173
174
|
const {isInMainSession, mainLocusUrl} = this;
|
|
174
175
|
if (isInMainSession || !mainLocusUrl) {
|
|
175
176
|
this.set('mainLocusUrl', locusUrl);
|
|
@@ -255,6 +256,10 @@ const Breakouts = WebexPlugin.extend({
|
|
|
255
256
|
* @returns {void}
|
|
256
257
|
*/
|
|
257
258
|
listenToBroadcastMessages() {
|
|
259
|
+
if (!this.webex.internal.llm.isConnected() || this.hasSubscribedToMessage) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
258
263
|
this.listenTo(this.webex.internal.llm, 'event:breakout.message', (event) => {
|
|
259
264
|
const {
|
|
260
265
|
data: {senderUserId, sentTime, message},
|
|
@@ -270,6 +275,7 @@ const Breakouts = WebexPlugin.extend({
|
|
|
270
275
|
sessionId: this.currentBreakoutSession.sessionId,
|
|
271
276
|
});
|
|
272
277
|
});
|
|
278
|
+
this.hasSubscribedToMessage = true;
|
|
273
279
|
},
|
|
274
280
|
|
|
275
281
|
/**
|
package/src/constants.ts
CHANGED
|
@@ -250,23 +250,6 @@ export const ASSIGN_ROLES_ERROR_CODES = {
|
|
|
250
250
|
ReclaimHostIsHostAlreadyErrorCode: 2409150,
|
|
251
251
|
};
|
|
252
252
|
|
|
253
|
-
export const DEFAULT_GET_STATS_FILTER = {
|
|
254
|
-
types: [
|
|
255
|
-
'track',
|
|
256
|
-
'transport',
|
|
257
|
-
'candidate-pair',
|
|
258
|
-
'outbound-rtp',
|
|
259
|
-
'outboundrtp',
|
|
260
|
-
'inbound-rtp',
|
|
261
|
-
'inboundrtp',
|
|
262
|
-
'remote-inbound-rtp',
|
|
263
|
-
'remote-outbound-rtp',
|
|
264
|
-
'remote-candidate',
|
|
265
|
-
'local-candidate',
|
|
266
|
-
'media-source',
|
|
267
|
-
],
|
|
268
|
-
};
|
|
269
|
-
|
|
270
253
|
export const RECORDING_STATE = {
|
|
271
254
|
RECORDING: 'recording',
|
|
272
255
|
IDLE: 'idle',
|
|
@@ -1331,3 +1314,16 @@ export const MEETING_PERMISSION_TOKEN_REFRESH_REASON = 'ttl-join';
|
|
|
1331
1314
|
|
|
1332
1315
|
// constant for named media group type
|
|
1333
1316
|
export const NAMED_MEDIA_GROUP_TYPE_AUDIO = 1;
|
|
1317
|
+
|
|
1318
|
+
export const DESTINATION_TYPE = {
|
|
1319
|
+
CONVERSATION_URL: 'CONVERSATION_URL',
|
|
1320
|
+
MEETING_LINK: 'MEETING_LINK',
|
|
1321
|
+
SIP_URI: 'SIP_URI',
|
|
1322
|
+
PERSONAL_ROOM: 'PERSONAL_ROOM',
|
|
1323
|
+
ONE_ON_ONE_CALL: 'ONE_ON_ONE_CALL',
|
|
1324
|
+
LOCUS_ID: 'LOCUS_ID',
|
|
1325
|
+
MEETING_ID: 'MEETING_ID',
|
|
1326
|
+
MEETING_UUID: 'MEETING_UUID',
|
|
1327
|
+
} as const;
|
|
1328
|
+
|
|
1329
|
+
export type DESTINATION_TYPE = Enum<typeof DESTINATION_TYPE>;
|
|
@@ -428,11 +428,6 @@ SelfUtils.mutedByOthersChanged = (oldSelf, changedSelf) => {
|
|
|
428
428
|
return false;
|
|
429
429
|
}
|
|
430
430
|
|
|
431
|
-
// there is no need to trigger user update if no one muted user
|
|
432
|
-
if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
431
|
return (
|
|
437
432
|
changedSelf.remoteMuted !== null &&
|
|
438
433
|
(oldSelf.remoteMuted !== changedSelf.remoteMuted ||
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {Defer} from '@webex/common';
|
|
2
|
-
import {ConnectionState,
|
|
2
|
+
import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
|
|
3
3
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
4
4
|
import {ICE_AND_DTLS_CONNECTION_TIMEOUT} from '../constants';
|
|
5
5
|
|
|
@@ -15,8 +15,10 @@ export default class MediaConnectionAwaiter {
|
|
|
15
15
|
private timer: any;
|
|
16
16
|
private defer: Defer;
|
|
17
17
|
private retried: boolean;
|
|
18
|
+
private iceConnected: boolean;
|
|
18
19
|
private onTimeoutCallback: () => void;
|
|
19
|
-
private
|
|
20
|
+
private peerConnectionStateCallback: () => void;
|
|
21
|
+
private iceConnectionStateCallback: () => void;
|
|
20
22
|
private iceGatheringStateCallback: () => void;
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -26,9 +28,11 @@ export default class MediaConnectionAwaiter {
|
|
|
26
28
|
this.webrtcMediaConnection = webrtcMediaConnection;
|
|
27
29
|
this.defer = new Defer();
|
|
28
30
|
this.retried = false;
|
|
31
|
+
this.iceConnected = false;
|
|
29
32
|
this.onTimeoutCallback = this.onTimeout.bind(this);
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
33
|
+
this.peerConnectionStateCallback = this.peerConnectionStateHandler.bind(this);
|
|
34
|
+
this.iceConnectionStateCallback = this.iceConnectionStateHandler.bind(this);
|
|
35
|
+
this.iceGatheringStateCallback = this.iceGatheringStateHandler.bind(this);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -40,6 +44,15 @@ export default class MediaConnectionAwaiter {
|
|
|
40
44
|
return this.webrtcMediaConnection.getConnectionState() === ConnectionState.Connected;
|
|
41
45
|
}
|
|
42
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Returns true if the connection is in an unrecoverable "failed" state
|
|
49
|
+
*
|
|
50
|
+
* @returns {boolean}
|
|
51
|
+
*/
|
|
52
|
+
private isFailed(): boolean {
|
|
53
|
+
return this.webrtcMediaConnection.getConnectionState() === ConnectionState.Failed;
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
/**
|
|
44
57
|
* Returns true if the ICE Gathering is completed, false otherwise.
|
|
45
58
|
*
|
|
@@ -56,22 +69,40 @@ export default class MediaConnectionAwaiter {
|
|
|
56
69
|
*/
|
|
57
70
|
private clearCallbacks(): void {
|
|
58
71
|
this.webrtcMediaConnection.off(
|
|
59
|
-
|
|
72
|
+
MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED,
|
|
60
73
|
this.iceGatheringStateCallback
|
|
61
74
|
);
|
|
62
|
-
this.webrtcMediaConnection.off(
|
|
75
|
+
this.webrtcMediaConnection.off(
|
|
76
|
+
MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
|
|
77
|
+
this.peerConnectionStateCallback
|
|
78
|
+
);
|
|
79
|
+
this.webrtcMediaConnection.off(
|
|
80
|
+
MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
|
|
81
|
+
this.iceConnectionStateCallback
|
|
82
|
+
);
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
/**
|
|
66
|
-
*
|
|
86
|
+
* On connection state change.
|
|
67
87
|
*
|
|
68
88
|
* @returns {void}
|
|
69
89
|
*/
|
|
70
|
-
|
|
90
|
+
connectionStateChange(): void {
|
|
71
91
|
LoggerProxy.logger.log(
|
|
72
|
-
`Media:MediaConnectionAwaiter#
|
|
92
|
+
`Media:MediaConnectionAwaiter#connectionStateChange --> connection state: ${this.webrtcMediaConnection.getConnectionState()}`
|
|
73
93
|
);
|
|
74
94
|
|
|
95
|
+
if (this.isFailed()) {
|
|
96
|
+
LoggerProxy.logger.warn(
|
|
97
|
+
'Media:MediaConnectionAwaiter#connectionStateChange --> ICE failed, rejecting'
|
|
98
|
+
);
|
|
99
|
+
this.clearCallbacks();
|
|
100
|
+
|
|
101
|
+
this.defer.reject({
|
|
102
|
+
iceConnected: this.iceConnected,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
75
106
|
if (!this.isConnected()) {
|
|
76
107
|
return;
|
|
77
108
|
}
|
|
@@ -83,16 +114,50 @@ export default class MediaConnectionAwaiter {
|
|
|
83
114
|
this.defer.resolve();
|
|
84
115
|
}
|
|
85
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Listener for peer connection state change.
|
|
119
|
+
*
|
|
120
|
+
* @returns {void}
|
|
121
|
+
*/
|
|
122
|
+
peerConnectionStateHandler(): void {
|
|
123
|
+
const peerConnectionState = this.webrtcMediaConnection.getPeerConnectionState();
|
|
124
|
+
|
|
125
|
+
LoggerProxy.logger.log(
|
|
126
|
+
`Media:MediaConnectionAwaiter#peerConnectionStateHandler --> Peer connection state change -> ${peerConnectionState}`
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
this.connectionStateChange();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Listener for ICE connection state change.
|
|
134
|
+
*
|
|
135
|
+
* @returns {void}
|
|
136
|
+
*/
|
|
137
|
+
iceConnectionStateHandler(): void {
|
|
138
|
+
const iceConnectionState = this.webrtcMediaConnection.getIceConnectionState();
|
|
139
|
+
|
|
140
|
+
LoggerProxy.logger.log(
|
|
141
|
+
`Media:MediaConnectionAwaiter#iceConnectionStateHandler --> ICE connection state change -> ${iceConnectionState}`
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
if (iceConnectionState === 'connected' && !this.iceConnected) {
|
|
145
|
+
this.iceConnected = true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.connectionStateChange();
|
|
149
|
+
}
|
|
150
|
+
|
|
86
151
|
/**
|
|
87
152
|
* Listener for ICE gathering state change.
|
|
88
153
|
*
|
|
89
154
|
* @returns {void}
|
|
90
155
|
*/
|
|
91
|
-
|
|
156
|
+
iceGatheringStateHandler(): void {
|
|
92
157
|
const iceGatheringState = this.webrtcMediaConnection.getIceGatheringState();
|
|
93
158
|
|
|
94
159
|
LoggerProxy.logger.log(
|
|
95
|
-
`Media:MediaConnectionAwaiter#
|
|
160
|
+
`Media:MediaConnectionAwaiter#iceGatheringStateHandler --> ICE gathering state change -> ${iceGatheringState}`
|
|
96
161
|
);
|
|
97
162
|
|
|
98
163
|
if (!this.isIceGatheringCompleted()) {
|
|
@@ -147,7 +212,9 @@ export default class MediaConnectionAwaiter {
|
|
|
147
212
|
|
|
148
213
|
this.clearCallbacks();
|
|
149
214
|
|
|
150
|
-
this.defer.reject(
|
|
215
|
+
this.defer.reject({
|
|
216
|
+
iceConnected: this.iceConnected,
|
|
217
|
+
});
|
|
151
218
|
}
|
|
152
219
|
|
|
153
220
|
/**
|
|
@@ -160,10 +227,18 @@ export default class MediaConnectionAwaiter {
|
|
|
160
227
|
return Promise.resolve();
|
|
161
228
|
}
|
|
162
229
|
|
|
163
|
-
this.webrtcMediaConnection.on(
|
|
230
|
+
this.webrtcMediaConnection.on(
|
|
231
|
+
MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
|
|
232
|
+
this.peerConnectionStateCallback
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
this.webrtcMediaConnection.on(
|
|
236
|
+
MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
|
|
237
|
+
this.iceConnectionStateCallback
|
|
238
|
+
);
|
|
164
239
|
|
|
165
240
|
this.webrtcMediaConnection.on(
|
|
166
|
-
|
|
241
|
+
MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED,
|
|
167
242
|
this.iceGatheringStateCallback
|
|
168
243
|
);
|
|
169
244
|
|
package/src/media/index.ts
CHANGED
|
@@ -163,6 +163,19 @@ Media.createMediaConnection = (
|
|
|
163
163
|
// we might not have any TURN server if TURN discovery failed or wasn't done or
|
|
164
164
|
// we might get an empty TURN url if we land on a video mesh node
|
|
165
165
|
if (turnServerInfo?.url) {
|
|
166
|
+
if (!isBrowser('firefox')) {
|
|
167
|
+
let bareTurnServer = turnServerInfo.url;
|
|
168
|
+
bareTurnServer = bareTurnServer.replace('turns:', 'turn:');
|
|
169
|
+
bareTurnServer = bareTurnServer.replace('443', '5004');
|
|
170
|
+
|
|
171
|
+
iceServers.push({
|
|
172
|
+
urls: bareTurnServer,
|
|
173
|
+
username: turnServerInfo.username || '',
|
|
174
|
+
credential: turnServerInfo.password || '',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// TURN-TLS server
|
|
166
179
|
iceServers.push({
|
|
167
180
|
urls: turnServerInfo.url,
|
|
168
181
|
username: turnServerInfo.username || '',
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {MediaConnectionEventNames, ConnectionState} from '@webex/internal-media-core';
|
|
2
|
+
import EventsScope from '../common/events/events-scope';
|
|
3
|
+
import {Enum} from '../constants';
|
|
4
|
+
|
|
5
|
+
export const ConnectionStateEvent = {
|
|
6
|
+
stateChanged: 'connectionState:changed',
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type ConnectionStateEvent = Enum<typeof ConnectionStateEvent>;
|
|
10
|
+
|
|
11
|
+
export interface ConnectionStateChangedEvent {
|
|
12
|
+
/**
|
|
13
|
+
* Current overall connection state
|
|
14
|
+
*/
|
|
15
|
+
state: ConnectionState;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @class ConnectionStateHandler
|
|
20
|
+
*/
|
|
21
|
+
export class ConnectionStateHandler extends EventsScope {
|
|
22
|
+
private webrtcMediaConnection: any;
|
|
23
|
+
|
|
24
|
+
private mediaConnectionState: ConnectionState;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {WebRTCMeeting} webrtcMediaConnection
|
|
28
|
+
*/
|
|
29
|
+
constructor(webrtcMediaConnection) {
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
this.webrtcMediaConnection = webrtcMediaConnection;
|
|
33
|
+
|
|
34
|
+
this.webrtcMediaConnection.on(
|
|
35
|
+
MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
|
|
36
|
+
this.handleConnectionStateChange.bind(this)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
this.webrtcMediaConnection.on(
|
|
40
|
+
MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
|
|
41
|
+
this.handleConnectionStateChange.bind(this)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Handler for connection state change.
|
|
47
|
+
*
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
private handleConnectionStateChange(): void {
|
|
51
|
+
const newConnectionState = this.webrtcMediaConnection.getConnectionState();
|
|
52
|
+
|
|
53
|
+
if (newConnectionState !== this.mediaConnectionState) {
|
|
54
|
+
this.mediaConnectionState = newConnectionState;
|
|
55
|
+
this.emit(
|
|
56
|
+
{
|
|
57
|
+
file: 'connectionStateHandler',
|
|
58
|
+
function: 'handleConnectionStateChange',
|
|
59
|
+
},
|
|
60
|
+
ConnectionStateEvent.stateChanged,
|
|
61
|
+
{state: this.mediaConnectionState}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|