@webex/plugin-meetings 3.0.0-beta.394 → 3.0.0-beta.396

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.
@@ -1 +1 @@
1
- {"version":3,"names":["Roap","attrs","options","roapRequest","RoapRequest","turnDiscovery","TurnDiscovery","resolve","then","meeting","webex","meetings","meetingCollection","getByKey","correlationId","roapMessage","messageType","ROAP","ROAP_TYPES","OK","version","ROAP_VERSION","seq","LoggerProxy","logger","log","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ANSWER","sdps","sdp","ERROR","errorType","tieBreaker","OFFER","headers","sendEmptyMediaId","preferTranscoding","isMultistream","ipVersion","MeetingUtil","getIpVersion","locus","mediaConnections","updateMediaConnections","roapAnswer","remoteSdp","JSON","parse","answerSeq","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_HTTP_RESPONSE_MISSING","isReconnecting","isForced","doTurnDiscovery","StatelessWebexPlugin"],"sources":["index.ts"],"sourcesContent":["// @ts-ignore\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport RoapRequest from './request';\nimport TurnDiscovery from './turnDiscovery';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\n\n/**\n * Roap options\n * @typedef {Object} RoapOptions\n * @property {String} sdp\n * @property {Meeting} meeting\n * @property {Number} seq\n * @property {Number} tieBreaker\n * @property {Boolean} reconnect\n */\n\n/**\n * @typedef {Object} SeqOptions\n * @property {String} correlationId\n * @property {String} mediaId\n * @property {Number} seq\n */\n\n/**\n * @class Roap\n * @export\n * @private\n */\nexport default class Roap extends StatelessWebexPlugin {\n attrs: any;\n lastRoapOffer: any;\n options: any;\n roapHandler: any;\n roapRequest: any;\n turnDiscovery: any;\n\n /**\n *\n * @param {Object} attrs\n * @param {Object} options\n */\n constructor(attrs: any, options: any) {\n super({}, options);\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.attrs = attrs;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.options = options;\n /**\n * The Roap Request Server Proxy Object\n * @instance\n * @type {RoapRequest}\n * @private\n * @memberof Roap\n */\n // @ts-ignore\n this.roapRequest = new RoapRequest({}, options);\n\n this.turnDiscovery = new TurnDiscovery(this.roapRequest);\n }\n\n /**\n *\n * @param {SeqOptions} options\n * @returns {null}\n * @memberof Roap\n */\n public sendRoapOK(options: any) {\n return Promise.resolve().then(() => {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: options.seq,\n };\n\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sending with seq ${options.seq}`);\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);\n });\n });\n }\n\n /**\n * Sends a ROAP answer...\n * @param {SeqOptions} options\n * @param {Boolean} options.audioMuted\n * @param {Boolean} options.videoMuted\n * @returns {Promise}\n * @memberof Roap\n */\n public sendRoapAnswer(options: any) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ANSWER,\n sdps: [options.sdp],\n version: ROAP.ROAP_VERSION,\n seq: options.seq,\n };\n\n return this.roapRequest.sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Sends a ROAP error...\n * @param {Object} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapError(options) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ERROR,\n version: ROAP.ROAP_VERSION,\n errorType: options.errorType,\n seq: options.seq,\n };\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n })\n .then(() => {\n LoggerProxy.logger.log(\n `Roap:index#sendRoapError --> ROAP ERROR sent with seq ${options.seq}`\n );\n });\n }\n\n /**\n * sends a roap media request\n * @param {RoapOptions} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapMediaRequest(options: any) {\n const {meeting, seq, sdp, tieBreaker} = options;\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OFFER,\n sdps: [sdp],\n version: ROAP.ROAP_VERSION,\n seq,\n tieBreaker,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n // The only time we want to send an empty media id is when we are reconnecting, because this way we tell Locus\n // that it needs to create a new confluence, but when reconnecting we always send TURN_DISCOVERY_REQUEST first,\n // so we don't need to ever send an empty media id here\n const sendEmptyMediaId = false;\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: sendEmptyMediaId ? '' : meeting.mediaId,\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n locusMediaRequest: meeting.locusMediaRequest,\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then(({locus, mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n\n let roapAnswer;\n\n if (mediaConnections?.[0]?.remoteSdp) {\n const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);\n\n if (remoteSdp.roapMessage) {\n const {\n seq: answerSeq,\n messageType,\n sdps,\n errorType,\n errorCause,\n headers,\n } = remoteSdp.roapMessage;\n\n roapAnswer = {\n seq: answerSeq,\n messageType,\n sdp: sdps[0],\n errorType,\n errorCause,\n headers,\n };\n }\n }\n\n if (!roapAnswer) {\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {\n correlationId: meeting.correlationId,\n messageType: 'ANSWER',\n isMultistream: meeting.isMultistream,\n });\n }\n\n return {locus, roapAnswer};\n });\n }\n\n /**\n * Performs a TURN server discovery procedure, which involves exchanging\n * some roap messages with the server. This exchange has to be done before\n * any other roap messages are sent\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting should be set to true if this is a new\n * media connection just after a reconnection\n * @param {Boolean} [isForced]\n * @returns {Promise}\n */\n doTurnDiscovery(meeting: Meeting, isReconnecting: boolean, isForced?: boolean) {\n return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["Roap","attrs","options","roapRequest","RoapRequest","turnDiscovery","TurnDiscovery","resolve","then","meeting","webex","meetings","meetingCollection","getByKey","correlationId","roapMessage","messageType","ROAP","ROAP_TYPES","OK","version","ROAP_VERSION","seq","LoggerProxy","logger","log","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ANSWER","sdps","sdp","ERROR","errorType","tieBreaker","OFFER","headers","sendEmptyMediaId","preferTranscoding","isMultistream","ipVersion","MeetingUtil","getIpVersion","locus","mediaConnections","updateMediaConnections","roapAnswer","remoteSdp","JSON","parse","answerSeq","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_HTTP_RESPONSE_MISSING","isReconnecting","isForced","doTurnDiscovery","generateTurnDiscoveryRequestMessage","httpResponse","handleTurnDiscoveryHttpResponse","abort","StatelessWebexPlugin"],"sources":["index.ts"],"sourcesContent":["// @ts-ignore\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport RoapRequest from './request';\nimport TurnDiscovery, {TurnDiscoveryResult} from './turnDiscovery';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\n\nexport {\n type TurnDiscoveryResult,\n type TurnServerInfo,\n type TurnDiscoverySkipReason,\n} from './turnDiscovery';\n\n/**\n * Roap options\n * @typedef {Object} RoapOptions\n * @property {String} sdp\n * @property {Meeting} meeting\n * @property {Number} seq\n * @property {Number} tieBreaker\n * @property {Boolean} reconnect\n */\n\n/**\n * @typedef {Object} SeqOptions\n * @property {String} correlationId\n * @property {String} mediaId\n * @property {Number} seq\n */\n\n/**\n * @class Roap\n * @export\n * @private\n */\nexport default class Roap extends StatelessWebexPlugin {\n attrs: any;\n lastRoapOffer: any;\n options: any;\n roapHandler: any;\n roapRequest: any;\n turnDiscovery: TurnDiscovery;\n\n /**\n *\n * @param {Object} attrs\n * @param {Object} options\n */\n constructor(attrs: any, options: any) {\n super({}, options);\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.attrs = attrs;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.options = options;\n /**\n * The Roap Request Server Proxy Object\n * @instance\n * @type {RoapRequest}\n * @private\n * @memberof Roap\n */\n // @ts-ignore\n this.roapRequest = new RoapRequest({}, options);\n\n this.turnDiscovery = new TurnDiscovery(this.roapRequest);\n }\n\n /**\n *\n * @param {SeqOptions} options\n * @returns {null}\n * @memberof Roap\n */\n public sendRoapOK(options: any) {\n return Promise.resolve().then(() => {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: options.seq,\n };\n\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sending with seq ${options.seq}`);\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);\n });\n });\n }\n\n /**\n * Sends a ROAP answer...\n * @param {SeqOptions} options\n * @param {Boolean} options.audioMuted\n * @param {Boolean} options.videoMuted\n * @returns {Promise}\n * @memberof Roap\n */\n public sendRoapAnswer(options: any) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ANSWER,\n sdps: [options.sdp],\n version: ROAP.ROAP_VERSION,\n seq: options.seq,\n };\n\n return this.roapRequest.sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Sends a ROAP error...\n * @param {Object} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapError(options) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey(\n 'correlationId',\n options.correlationId\n );\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ERROR,\n version: ROAP.ROAP_VERSION,\n errorType: options.errorType,\n seq: options.seq,\n };\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n })\n .then(() => {\n LoggerProxy.logger.log(\n `Roap:index#sendRoapError --> ROAP ERROR sent with seq ${options.seq}`\n );\n });\n }\n\n /**\n * sends a roap media request\n * @param {RoapOptions} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapMediaRequest(options: any) {\n const {meeting, seq, sdp, tieBreaker} = options;\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OFFER,\n sdps: [sdp],\n version: ROAP.ROAP_VERSION,\n seq,\n tieBreaker,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n // The only time we want to send an empty media id is when we are reconnecting, because this way we tell Locus\n // that it needs to create a new confluence, but when reconnecting we always send TURN_DISCOVERY_REQUEST first,\n // so we don't need to ever send an empty media id here\n const sendEmptyMediaId = false;\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: sendEmptyMediaId ? '' : meeting.mediaId,\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n locusMediaRequest: meeting.locusMediaRequest,\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then(({locus, mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n\n let roapAnswer;\n\n if (mediaConnections?.[0]?.remoteSdp) {\n const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);\n\n if (remoteSdp.roapMessage) {\n const {\n seq: answerSeq,\n messageType,\n sdps,\n errorType,\n errorCause,\n headers,\n } = remoteSdp.roapMessage;\n\n roapAnswer = {\n seq: answerSeq,\n messageType,\n sdp: sdps[0],\n errorType,\n errorCause,\n headers,\n };\n }\n }\n\n if (!roapAnswer) {\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {\n correlationId: meeting.correlationId,\n messageType: 'ANSWER',\n isMultistream: meeting.isMultistream,\n });\n }\n\n return {locus, roapAnswer};\n });\n }\n\n /**\n * Performs a TURN server discovery procedure, which involves exchanging\n * some roap messages with the server. This exchange has to be done before\n * any other roap messages are sent\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting should be set to true if this is a new\n * media connection just after a reconnection\n * @param {Boolean} [isForced]\n * @returns {Promise}\n */\n doTurnDiscovery(\n meeting: Meeting,\n isReconnecting: boolean,\n isForced?: boolean\n ): Promise<TurnDiscoveryResult> {\n return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);\n }\n\n generateTurnDiscoveryRequestMessage(meeting: Meeting, isForced: boolean) {\n return this.turnDiscovery.generateTurnDiscoveryRequestMessage(meeting, isForced);\n }\n\n handleTurnDiscoveryHttpResponse(meeting: Meeting, httpResponse: object) {\n return this.turnDiscovery.handleTurnDiscoveryHttpResponse(meeting, httpResponse);\n }\n\n abortTurnDiscovery() {\n return this.turnDiscovery.abort();\n }\n}\n"],"mappings":"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"}
@@ -28,7 +28,13 @@ var TURN_DISCOVERY_TIMEOUT = 10; // in seconds
28
28
  // so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection
29
29
  // and do the SDP offer with seq=1
30
30
  var TURN_DISCOVERY_SEQ = 0;
31
-
31
+ var TurnDiscoverySkipReason = {
32
+ missingHttpResponse: 'missing http response',
33
+ // when we asked for the TURN discovery response to be in the http response, but it wasn't there
34
+ reachability: 'reachability',
35
+ // when udp reachability to public clusters is ok, so we don't need TURN (this doens't apply when joinWithMedia() is used)
36
+ alreadyInProgress: 'already in progress' // when we try to start TURN discovery while it's already in progress
37
+ };
32
38
  /**
33
39
  * Handles the process of finding out TURN server information from Linus.
34
40
  * This is achieved by sending a TURN_DISCOVERY_REQUEST.
@@ -79,7 +85,8 @@ var TurnDiscovery = /*#__PURE__*/function () {
79
85
  }
80
86
 
81
87
  /**
82
- * handles TURN_DISCOVERY_RESPONSE roap message
88
+ * Handles TURN_DISCOVERY_RESPONSE roap message. Use it if the roap message comes over the websocket,
89
+ * otherwise use handleTurnDiscoveryHttpResponse() if it comes in the http response.
83
90
  *
84
91
  * @param {Object} roapMessage
85
92
  * @param {string} from string to indicate how we got the response (used just for logging)
@@ -133,32 +140,233 @@ var TurnDiscovery = /*#__PURE__*/function () {
133
140
  }
134
141
 
135
142
  /**
136
- * handles TURN_DISCOVERY_RESPONSE roap message that came in http response
143
+ * Generates TURN_DISCOVERY_REQUEST roap message. When this method returns a roapMessage, it means that a TURN discovery process has started.
144
+ * It needs be ended by calling handleTurnDiscoveryHttpResponse() once you get a response from the backend. If you don't get any response
145
+ * or want to abort, you need to call abort().
137
146
  *
138
- * @param {Object} roapMessage
139
- * @returns {Promise}
140
- * @memberof Roap
147
+ * @param {Meeting} meeting
148
+ * @param {boolean} isForced
149
+ * @returns {Object}
141
150
  */
142
151
  }, {
143
- key: "handleTurnDiscoveryResponseInHttpResponse",
152
+ key: "generateTurnDiscoveryRequestMessage",
144
153
  value: function () {
145
- var _handleTurnDiscoveryResponseInHttpResponse = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(roapMessage) {
154
+ var _generateTurnDiscoveryRequestMessage = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(meeting, isForced) {
155
+ var turnDiscoverySkippedReason, roapMessage;
146
156
  return _regenerator.default.wrap(function _callee$(_context) {
147
157
  while (1) switch (_context.prev = _context.next) {
148
158
  case 0:
149
- this.handleTurnDiscoveryResponse(roapMessage, 'in http response');
150
- return _context.abrupt("return", this.defer.promise);
151
- case 2:
159
+ if (!this.defer) {
160
+ _context.next = 3;
161
+ break;
162
+ }
163
+ _loggerProxy.default.logger.warn('Roap:turnDiscovery#generateTurnDiscoveryRequestMessage --> TURN discovery already in progress');
164
+ return _context.abrupt("return", {
165
+ roapMessage: undefined,
166
+ turnDiscoverySkippedReason: TurnDiscoverySkipReason.alreadyInProgress
167
+ });
168
+ case 3:
169
+ if (isForced) {
170
+ _context.next = 7;
171
+ break;
172
+ }
173
+ _context.next = 6;
174
+ return this.getSkipReason(meeting);
175
+ case 6:
176
+ turnDiscoverySkippedReason = _context.sent;
177
+ case 7:
178
+ if (!turnDiscoverySkippedReason) {
179
+ _context.next = 9;
180
+ break;
181
+ }
182
+ return _context.abrupt("return", {
183
+ roapMessage: undefined,
184
+ turnDiscoverySkippedReason: turnDiscoverySkippedReason
185
+ });
186
+ case 9:
187
+ this.defer = new _common.Defer();
188
+ roapMessage = {
189
+ messageType: _constants2.ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,
190
+ version: _constants2.ROAP.ROAP_VERSION,
191
+ seq: TURN_DISCOVERY_SEQ,
192
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction']
193
+ };
194
+ _loggerProxy.default.logger.info('Roap:turnDiscovery#generateTurnDiscoveryRequestMessage --> generated TURN_DISCOVERY_REQUEST message');
195
+ return _context.abrupt("return", {
196
+ roapMessage: roapMessage,
197
+ turnDiscoverySkippedReason: undefined
198
+ });
199
+ case 13:
152
200
  case "end":
153
201
  return _context.stop();
154
202
  }
155
203
  }, _callee, this);
156
204
  }));
157
- function handleTurnDiscoveryResponseInHttpResponse(_x) {
158
- return _handleTurnDiscoveryResponseInHttpResponse.apply(this, arguments);
205
+ function generateTurnDiscoveryRequestMessage(_x, _x2) {
206
+ return _generateTurnDiscoveryRequestMessage.apply(this, arguments);
159
207
  }
160
- return handleTurnDiscoveryResponseInHttpResponse;
208
+ return generateTurnDiscoveryRequestMessage;
161
209
  }()
210
+ /**
211
+ * Handles any errors that occur during TURN discovery without re-throwing them.
212
+ *
213
+ * @param {Meeting} meeting
214
+ * @param {Error} error
215
+ * @returns {TurnDiscoveryResult}
216
+ */
217
+ }, {
218
+ key: "handleTurnDiscoveryFailure",
219
+ value: function handleTurnDiscoveryFailure(meeting, error) {
220
+ // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
221
+ _loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(error));
222
+ _metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
223
+ correlation_id: meeting.correlationId,
224
+ locus_id: meeting.locusUrl.split('/').pop(),
225
+ reason: error.message,
226
+ stack: error.stack
227
+ });
228
+ return {
229
+ turnServerInfo: undefined,
230
+ turnDiscoverySkippedReason: "failure: ".concat(error.message)
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Handles TURN_DISCOVERY_RESPONSE roap message that came in http response. If the response is not valid,
236
+ * it returns an object with turnServerInfo set to undefined. In that case you need to call abort()
237
+ * to end the TURN discovery process.
238
+ *
239
+ * @param {Meeting} meeting
240
+ * @param {Object|undefined} httpResponse can be undefined to indicate that we didn't get the response
241
+ * @returns {Promise<TurnDiscoveryResult>}
242
+ * @memberof Roap
243
+ */
244
+ }, {
245
+ key: "handleTurnDiscoveryHttpResponse",
246
+ value: function () {
247
+ var _handleTurnDiscoveryHttpResponse = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(meeting, httpResponse) {
248
+ var roapMessage, _yield$this$defer$pro, isOkRequired;
249
+ return _regenerator.default.wrap(function _callee2$(_context2) {
250
+ while (1) switch (_context2.prev = _context2.next) {
251
+ case 0:
252
+ if (this.defer) {
253
+ _context2.next = 3;
254
+ break;
255
+ }
256
+ _loggerProxy.default.logger.warn('Roap:turnDiscovery#handleTurnDiscoveryHttpResponse --> unexpected http response, TURN discovery is not in progress');
257
+ throw new Error('handleTurnDiscoveryHttpResponse() called before generateTurnDiscoveryRequestMessage()');
258
+ case 3:
259
+ if (!(httpResponse === undefined)) {
260
+ _context2.next = 5;
261
+ break;
262
+ }
263
+ return _context2.abrupt("return", {
264
+ turnServerInfo: undefined,
265
+ turnDiscoverySkippedReason: TurnDiscoverySkipReason.missingHttpResponse
266
+ });
267
+ case 5:
268
+ _context2.prev = 5;
269
+ roapMessage = this.parseHttpTurnDiscoveryResponse(meeting, httpResponse);
270
+ if (roapMessage) {
271
+ _context2.next = 9;
272
+ break;
273
+ }
274
+ return _context2.abrupt("return", {
275
+ turnServerInfo: undefined,
276
+ turnDiscoverySkippedReason: TurnDiscoverySkipReason.missingHttpResponse
277
+ });
278
+ case 9:
279
+ this.handleTurnDiscoveryResponse(roapMessage, 'in http response');
280
+ _context2.next = 12;
281
+ return this.defer.promise;
282
+ case 12:
283
+ _yield$this$defer$pro = _context2.sent;
284
+ isOkRequired = _yield$this$defer$pro.isOkRequired;
285
+ if (!isOkRequired) {
286
+ _context2.next = 17;
287
+ break;
288
+ }
289
+ _context2.next = 17;
290
+ return this.sendRoapOK(meeting);
291
+ case 17:
292
+ this.defer = undefined;
293
+ _loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
294
+ return _context2.abrupt("return", {
295
+ turnServerInfo: this.turnInfo,
296
+ turnDiscoverySkippedReason: undefined
297
+ });
298
+ case 22:
299
+ _context2.prev = 22;
300
+ _context2.t0 = _context2["catch"](5);
301
+ this.abort();
302
+ return _context2.abrupt("return", this.handleTurnDiscoveryFailure(meeting, _context2.t0));
303
+ case 26:
304
+ case "end":
305
+ return _context2.stop();
306
+ }
307
+ }, _callee2, this, [[5, 22]]);
308
+ }));
309
+ function handleTurnDiscoveryHttpResponse(_x3, _x4) {
310
+ return _handleTurnDiscoveryHttpResponse.apply(this, arguments);
311
+ }
312
+ return handleTurnDiscoveryHttpResponse;
313
+ }()
314
+ /**
315
+ * Aborts current TURN discovery. This method needs to be called if you called generateTurnDiscoveryRequestMessage(),
316
+ * but then never got any response from the server.
317
+ * @returns {void}
318
+ */
319
+ }, {
320
+ key: "abort",
321
+ value: function abort() {
322
+ if (this.defer) {
323
+ this.defer.reject(new Error('TURN discovery aborted'));
324
+ this.defer = undefined;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Parses the TURN_DISCOVERY_RESPONSE roap message out of the http response
330
+ * and returns it.
331
+ *
332
+ * @param {Meeting} meeting
333
+ * @param {any} httpResponse
334
+ * @returns {any}
335
+ */
336
+ }, {
337
+ key: "parseHttpTurnDiscoveryResponse",
338
+ value: function parseHttpTurnDiscoveryResponse(meeting, httpResponse) {
339
+ var _httpResponse$mediaCo, _httpResponse$mediaCo2;
340
+ var turnDiscoveryResponse;
341
+ if ((_httpResponse$mediaCo = httpResponse.mediaConnections) !== null && _httpResponse$mediaCo !== void 0 && (_httpResponse$mediaCo2 = _httpResponse$mediaCo[0]) !== null && _httpResponse$mediaCo2 !== void 0 && _httpResponse$mediaCo2.remoteSdp) {
342
+ var remoteSdp = JSON.parse(httpResponse.mediaConnections[0].remoteSdp);
343
+ if (remoteSdp.roapMessage) {
344
+ // yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...
345
+ var _remoteSdp$roapMessag = remoteSdp.roapMessage,
346
+ seq = _remoteSdp$roapMessag.seq,
347
+ messageType = _remoteSdp$roapMessag.messageType,
348
+ errorType = _remoteSdp$roapMessag.errorType,
349
+ errorCause = _remoteSdp$roapMessag.errorCause,
350
+ headers = _remoteSdp$roapMessag.headers;
351
+ turnDiscoveryResponse = {
352
+ seq: seq,
353
+ messageType: messageType,
354
+ errorType: errorType,
355
+ errorCause: errorCause,
356
+ headers: headers
357
+ };
358
+ }
359
+ }
360
+ if (!turnDiscoveryResponse) {
361
+ _metrics.default.sendBehavioralMetric(_constants.default.ROAP_HTTP_RESPONSE_MISSING, {
362
+ correlationId: meeting.correlationId,
363
+ messageType: 'TURN_DISCOVERY_RESPONSE',
364
+ isMultistream: meeting.isMultistream
365
+ });
366
+ }
367
+ return turnDiscoveryResponse;
368
+ }
369
+
162
370
  /**
163
371
  * sends the TURN_DISCOVERY_REQUEST roap request
164
372
  *
@@ -171,9 +379,13 @@ var TurnDiscovery = /*#__PURE__*/function () {
171
379
  }, {
172
380
  key: "sendRoapTurnDiscoveryRequest",
173
381
  value: function sendRoapTurnDiscoveryRequest(meeting, isReconnecting) {
382
+ var _this2 = this;
174
383
  if (this.defer) {
175
384
  _loggerProxy.default.logger.warn('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress');
176
- return _promise.default.resolve();
385
+ return _promise.default.resolve({
386
+ turnServerInfo: undefined,
387
+ turnDiscoverySkippedReason: TurnDiscoverySkipReason.alreadyInProgress
388
+ });
177
389
  }
178
390
  this.defer = new _common.Defer();
179
391
  var roapMessage = {
@@ -193,41 +405,27 @@ var TurnDiscovery = /*#__PURE__*/function () {
193
405
  locusMediaRequest: meeting.locusMediaRequest,
194
406
  // @ts-ignore - because of meeting.webex
195
407
  ipVersion: _util.default.getIpVersion(meeting.webex)
196
- }).then(function (response) {
197
- var mediaConnections = response.mediaConnections;
198
- var turnDiscoveryResponse;
199
- if (mediaConnections) {
200
- var _mediaConnections$;
201
- meeting.updateMediaConnections(mediaConnections);
202
- if ((_mediaConnections$ = mediaConnections[0]) !== null && _mediaConnections$ !== void 0 && _mediaConnections$.remoteSdp) {
203
- var remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
204
- if (remoteSdp.roapMessage) {
205
- // yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...
206
- var _remoteSdp$roapMessag = remoteSdp.roapMessage,
207
- seq = _remoteSdp$roapMessag.seq,
208
- messageType = _remoteSdp$roapMessag.messageType,
209
- errorType = _remoteSdp$roapMessag.errorType,
210
- errorCause = _remoteSdp$roapMessag.errorCause,
211
- headers = _remoteSdp$roapMessag.headers;
212
- turnDiscoveryResponse = {
213
- seq: seq,
214
- messageType: messageType,
215
- errorType: errorType,
216
- errorCause: errorCause,
217
- headers: headers
218
- };
408
+ }).then( /*#__PURE__*/function () {
409
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(response) {
410
+ var mediaConnections;
411
+ return _regenerator.default.wrap(function _callee3$(_context3) {
412
+ while (1) switch (_context3.prev = _context3.next) {
413
+ case 0:
414
+ mediaConnections = response.mediaConnections;
415
+ if (mediaConnections) {
416
+ meeting.updateMediaConnections(mediaConnections);
417
+ }
418
+ return _context3.abrupt("return", _this2.handleTurnDiscoveryHttpResponse(meeting, response));
419
+ case 3:
420
+ case "end":
421
+ return _context3.stop();
219
422
  }
220
- }
221
- }
222
- if (!turnDiscoveryResponse) {
223
- _metrics.default.sendBehavioralMetric(_constants.default.ROAP_HTTP_RESPONSE_MISSING, {
224
- correlationId: meeting.correlationId,
225
- messageType: 'TURN_DISCOVERY_RESPONSE',
226
- isMultistream: meeting.isMultistream
227
- });
228
- }
229
- return turnDiscoveryResponse;
230
- });
423
+ }, _callee3);
424
+ }));
425
+ return function (_x5) {
426
+ return _ref.apply(this, arguments);
427
+ };
428
+ }());
231
429
  }
232
430
 
233
431
  /**
@@ -240,7 +438,11 @@ var TurnDiscovery = /*#__PURE__*/function () {
240
438
  }, {
241
439
  key: "sendRoapOK",
242
440
  value: function sendRoapOK(meeting) {
243
- _loggerProxy.default.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');
441
+ _loggerProxy.default.logger.info('Roap:turnDiscovery#sendRoapOK --> TURN discovery response requires OK, sending it...');
442
+ _metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_REQUIRES_OK, {
443
+ correlation_id: meeting.correlationId,
444
+ locus_id: meeting.locusUrl.split('/').pop()
445
+ });
244
446
  return this.roapRequest.sendRoap({
245
447
  roapMessage: {
246
448
  messageType: _constants2.ROAP.ROAP_TYPES.OK,
@@ -265,30 +467,30 @@ var TurnDiscovery = /*#__PURE__*/function () {
265
467
  }, {
266
468
  key: "getSkipReason",
267
469
  value: function () {
268
- var _getSkipReason = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(meeting) {
470
+ var _getSkipReason = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(meeting) {
269
471
  var isAnyPublicClusterReachable;
270
- return _regenerator.default.wrap(function _callee2$(_context2) {
271
- while (1) switch (_context2.prev = _context2.next) {
472
+ return _regenerator.default.wrap(function _callee4$(_context4) {
473
+ while (1) switch (_context4.prev = _context4.next) {
272
474
  case 0:
273
- _context2.next = 2;
475
+ _context4.next = 2;
274
476
  return meeting.webex.meetings.reachability.isAnyPublicClusterReachable();
275
477
  case 2:
276
- isAnyPublicClusterReachable = _context2.sent;
478
+ isAnyPublicClusterReachable = _context4.sent;
277
479
  if (!isAnyPublicClusterReachable) {
278
- _context2.next = 6;
480
+ _context4.next = 6;
279
481
  break;
280
482
  }
281
483
  _loggerProxy.default.logger.info('Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery');
282
- return _context2.abrupt("return", 'reachability');
484
+ return _context4.abrupt("return", TurnDiscoverySkipReason.reachability);
283
485
  case 6:
284
- return _context2.abrupt("return", '');
486
+ return _context4.abrupt("return", undefined);
285
487
  case 7:
286
488
  case "end":
287
- return _context2.stop();
489
+ return _context4.stop();
288
490
  }
289
- }, _callee2);
491
+ }, _callee4);
290
492
  }));
291
- function getSkipReason(_x2) {
493
+ function getSkipReason(_x6) {
292
494
  return _getSkipReason.apply(this, arguments);
293
495
  }
294
496
  return getSkipReason;
@@ -302,23 +504,23 @@ var TurnDiscovery = /*#__PURE__*/function () {
302
504
  }, {
303
505
  key: "isSkipped",
304
506
  value: function () {
305
- var _isSkipped = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(meeting) {
507
+ var _isSkipped = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(meeting) {
306
508
  var skipReason;
307
- return _regenerator.default.wrap(function _callee3$(_context3) {
308
- while (1) switch (_context3.prev = _context3.next) {
509
+ return _regenerator.default.wrap(function _callee5$(_context5) {
510
+ while (1) switch (_context5.prev = _context5.next) {
309
511
  case 0:
310
- _context3.next = 2;
512
+ _context5.next = 2;
311
513
  return this.getSkipReason(meeting);
312
514
  case 2:
313
- skipReason = _context3.sent;
314
- return _context3.abrupt("return", !!skipReason);
515
+ skipReason = _context5.sent;
516
+ return _context5.abrupt("return", !!skipReason);
315
517
  case 4:
316
518
  case "end":
317
- return _context3.stop();
519
+ return _context5.stop();
318
520
  }
319
- }, _callee3, this);
521
+ }, _callee5, this);
320
522
  }));
321
- function isSkipped(_x3) {
523
+ function isSkipped(_x7) {
322
524
  return _isSkipped.apply(this, arguments);
323
525
  }
324
526
  return isSkipped;
@@ -344,93 +546,69 @@ var TurnDiscovery = /*#__PURE__*/function () {
344
546
  }, {
345
547
  key: "doTurnDiscovery",
346
548
  value: function () {
347
- var _doTurnDiscovery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(meeting, isReconnecting, isForced) {
348
- var turnDiscoverySkippedReason, httpResponse, _ref, isOkRequired;
349
- return _regenerator.default.wrap(function _callee4$(_context4) {
350
- while (1) switch (_context4.prev = _context4.next) {
549
+ var _doTurnDiscovery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(meeting, isReconnecting, isForced) {
550
+ var turnDiscoverySkippedReason, turnDiscoveryResult, _yield$this$waitForTu, isOkRequired;
551
+ return _regenerator.default.wrap(function _callee6$(_context6) {
552
+ while (1) switch (_context6.prev = _context6.next) {
351
553
  case 0:
352
554
  if (isForced) {
353
- _context4.next = 4;
555
+ _context6.next = 4;
354
556
  break;
355
557
  }
356
- _context4.next = 3;
558
+ _context6.next = 3;
357
559
  return this.getSkipReason(meeting);
358
560
  case 3:
359
- turnDiscoverySkippedReason = _context4.sent;
561
+ turnDiscoverySkippedReason = _context6.sent;
360
562
  case 4:
361
563
  if (!turnDiscoverySkippedReason) {
362
- _context4.next = 6;
564
+ _context6.next = 6;
363
565
  break;
364
566
  }
365
- return _context4.abrupt("return", {
567
+ return _context6.abrupt("return", {
366
568
  turnServerInfo: undefined,
367
569
  turnDiscoverySkippedReason: turnDiscoverySkippedReason
368
570
  });
369
571
  case 6:
370
- _context4.prev = 6;
371
- _context4.next = 9;
572
+ _context6.prev = 6;
573
+ _context6.next = 9;
372
574
  return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting);
373
575
  case 9:
374
- httpResponse = _context4.sent;
375
- if (!httpResponse) {
376
- _context4.next = 16;
576
+ turnDiscoveryResult = _context6.sent;
577
+ if (!(turnDiscoveryResult.turnDiscoverySkippedReason !== TurnDiscoverySkipReason.missingHttpResponse)) {
578
+ _context6.next = 12;
377
579
  break;
378
580
  }
379
- _context4.next = 13;
380
- return this.handleTurnDiscoveryResponseInHttpResponse(httpResponse);
381
- case 13:
382
- _context4.t0 = _context4.sent;
383
- _context4.next = 19;
384
- break;
385
- case 16:
386
- _context4.next = 18;
581
+ return _context6.abrupt("return", turnDiscoveryResult);
582
+ case 12:
583
+ _context6.next = 14;
387
584
  return this.waitForTurnDiscoveryResponse();
388
- case 18:
389
- _context4.t0 = _context4.sent;
390
- case 19:
391
- _ref = _context4.t0;
392
- isOkRequired = _ref.isOkRequired;
585
+ case 14:
586
+ _yield$this$waitForTu = _context6.sent;
587
+ isOkRequired = _yield$this$waitForTu.isOkRequired;
393
588
  if (!isOkRequired) {
394
- _context4.next = 26;
589
+ _context6.next = 19;
395
590
  break;
396
591
  }
397
- _context4.next = 24;
592
+ _context6.next = 19;
398
593
  return this.sendRoapOK(meeting);
399
- case 24:
400
- _loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery response requires OK');
401
- _metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_REQUIRES_OK, {
402
- correlation_id: meeting.correlationId,
403
- locus_id: meeting.locusUrl.split('/').pop()
404
- });
405
- case 26:
594
+ case 19:
406
595
  this.defer = undefined;
407
596
  _loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
408
- return _context4.abrupt("return", {
597
+ return _context6.abrupt("return", {
409
598
  turnServerInfo: this.turnInfo,
410
599
  turnDiscoverySkippedReason: undefined
411
600
  });
412
- case 31:
413
- _context4.prev = 31;
414
- _context4.t1 = _context4["catch"](6);
415
- // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
416
- _loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(_context4.t1));
417
- _metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
418
- correlation_id: meeting.correlationId,
419
- locus_id: meeting.locusUrl.split('/').pop(),
420
- reason: _context4.t1.message,
421
- stack: _context4.t1.stack
422
- });
423
- return _context4.abrupt("return", {
424
- turnServerInfo: undefined,
425
- turnDiscoverySkippedReason: undefined
426
- });
427
- case 36:
601
+ case 24:
602
+ _context6.prev = 24;
603
+ _context6.t0 = _context6["catch"](6);
604
+ return _context6.abrupt("return", this.handleTurnDiscoveryFailure(meeting, _context6.t0));
605
+ case 27:
428
606
  case "end":
429
- return _context4.stop();
607
+ return _context6.stop();
430
608
  }
431
- }, _callee4, this, [[6, 31]]);
609
+ }, _callee6, this, [[6, 24]]);
432
610
  }));
433
- function doTurnDiscovery(_x4, _x5, _x6) {
611
+ function doTurnDiscovery(_x8, _x9, _x10) {
434
612
  return _doTurnDiscovery.apply(this, arguments);
435
613
  }
436
614
  return doTurnDiscovery;