@webex/plugin-meetings 3.8.0-next.65 → 3.8.0-next.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/index.js +7 -1
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/index.js +4 -1
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +23 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/clusterReachability.js +1 -0
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/types/config.d.ts +1 -0
- package/dist/types/meetings/index.d.ts +10 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/config.ts +1 -0
- package/src/media/index.ts +9 -0
- package/src/meeting/index.ts +3 -0
- package/src/meetings/index.ts +21 -0
- package/src/reachability/clusterReachability.ts +1 -0
- package/test/unit/spec/media/index.ts +62 -0
- package/test/unit/spec/meetings/index.js +13 -0
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["_common","require","_loggerProxy","_interopRequireDefault","_util","_eventsScope","_constants","_reachability","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","Events","exports","resultReady","clientMediaIpsUpdated","natTypeUpdated","ClusterReachability","_EventsScope","_inherits2","_super","name","clusterInfo","_this","_classCallCheck2","_assertThisInitialized2","_set","isVideoMesh","numUdpUrls","udp","numTcpUrls","tcp","numXTlsUrls","xtls","pc","createPeerConnection","defer","Defer","_createClass2","key","value","getElapsedTime","Math","round","performance","now","startTimestamp","buildPeerConnectionConfig","cluster","udpIceServers","map","url","username","credential","urls","tcpIceServers","urlString","convertStunUrlToTurn","turnTlsIceServers","convertStunUrlToTurnTls","iceServers","concat","_toConsumableArray2","iceCandidatePoolSize","iceTransportPolicy","config","peerConnection","RTCPeerConnection","peerConnectionError","LoggerProxy","logger","warn","undefined","getResult","closePeerConnection","onicecandidate","onicegatheringstatechange","close","finishReachabilityCheck","resolve","abort","CLOSED","CONNECTION_STATE","connectionState","addPublicIP","protocol","publicIP","ipAdded","clientMediaIPs","includes","emit","file","function","registerIceGatheringStateChangeListener","_this2","iceGatheringState","ICE_GATHERING_STATE","COMPLETE","saveResult","latency","publicIp","serverIp","latencyInMilliseconds","log","reachedSubnets","add","determineNatType","candidate","_this3","srflxIceCandidates","portsFound","c","address","relatedPort","port","_entries","_ref","_ref2","_slicedToArray2","ports","size","natType","NatType","SymmetricNat","registerIceCandidateListener","_this4","TURN_TLS_PORT","CANDIDATE_TYPES","SERVER_REFLEXIVE","RELAY","type","stunServerUrlRegex","match","_start","_asyncToGenerator2","_regenerator","mark","_callee","offer","gatherIceCandidatePromise","wrap","_callee$","_context","prev","next","abrupt","createOffer","offerToReceiveAudio","sent","gatherIceCandidates","setLocalDescription","t0","stop","start","promise","EventsScope"],"sources":["clusterReachability.ts"],"sourcesContent":["import {Defer} from '@webex/common';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ClusterNode} from './request';\nimport {convertStunUrlToTurn, convertStunUrlToTurnTls} from './util';\nimport EventsScope from '../common/events/events-scope';\n\nimport {CONNECTION_STATE, Enum, ICE_GATHERING_STATE} from '../constants';\nimport {ClusterReachabilityResult, NatType} from './reachability.types';\n\n// data for the Events.resultReady event\nexport type ResultEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n result: 'reachable' | 'unreachable' | 'untested';\n latencyInMilliseconds: number; // amount of time it took to get the ICE candidate\n clientMediaIPs?: string[];\n};\n\n// data for the Events.clientMediaIpsUpdated event\nexport type ClientMediaIpsUpdatedEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n clientMediaIPs: string[];\n};\n\nexport type NatTypeUpdatedEventData = {\n natType: NatType;\n};\n\nexport const Events = {\n resultReady: 'resultReady', // emitted when a cluster is reached successfully using specific protocol\n clientMediaIpsUpdated: 'clientMediaIpsUpdated', // emitted when more public IPs are found after resultReady was already sent for a given protocol\n natTypeUpdated: 'natTypeUpdated', // emitted when NAT type is determined\n} as const;\n\nexport type Events = Enum<typeof Events>;\n\n/**\n * A class that handles reachability checks for a single cluster.\n * It emits events from Events enum\n */\nexport class ClusterReachability extends EventsScope {\n private numUdpUrls: number;\n private numTcpUrls: number;\n private numXTlsUrls: number;\n private result: ClusterReachabilityResult;\n private pc?: RTCPeerConnection;\n private defer: Defer; // this defer is resolved once reachability checks for this cluster are completed\n private startTimestamp: number;\n private srflxIceCandidates: RTCIceCandidate[] = [];\n public readonly isVideoMesh: boolean;\n public readonly name;\n public readonly reachedSubnets: Set<string> = new Set();\n\n /**\n * Constructor for ClusterReachability\n * @param {string} name cluster name\n * @param {ClusterNode} clusterInfo information about the media cluster\n */\n constructor(name: string, clusterInfo: ClusterNode) {\n super();\n this.name = name;\n this.isVideoMesh = clusterInfo.isVideoMesh;\n this.numUdpUrls = clusterInfo.udp.length;\n this.numTcpUrls = clusterInfo.tcp.length;\n this.numXTlsUrls = clusterInfo.xtls.length;\n\n this.pc = this.createPeerConnection(clusterInfo);\n\n this.defer = new Defer();\n this.result = {\n udp: {\n result: 'untested',\n },\n tcp: {\n result: 'untested',\n },\n xtls: {\n result: 'untested',\n },\n };\n }\n\n /**\n * Gets total elapsed time, can be called only after start() is called\n * @returns {Number} Milliseconds\n */\n private getElapsedTime() {\n return Math.round(performance.now() - this.startTimestamp);\n }\n\n /**\n * Generate peerConnection config settings\n * @param {ClusterNode} cluster\n * @returns {RTCConfiguration} peerConnectionConfig\n */\n private buildPeerConnectionConfig(cluster: ClusterNode): RTCConfiguration {\n const udpIceServers = cluster.udp.map((url) => ({\n username: '',\n credential: '',\n urls: [url],\n }));\n\n // STUN servers are contacted only using UDP, so in order to test TCP reachability\n // we pretend that Linus is a TURN server, because we can explicitly say \"transport=tcp\" in TURN urls.\n // We then check for relay candidates to know if TURN-TCP worked (see registerIceCandidateListener()).\n const tcpIceServers = cluster.tcp.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurn(urlString, 'tcp')],\n };\n });\n\n const turnTlsIceServers = cluster.xtls.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurnTls(urlString)],\n };\n });\n\n return {\n iceServers: [...udpIceServers, ...tcpIceServers, ...turnTlsIceServers],\n iceCandidatePoolSize: 0,\n iceTransportPolicy: 'all',\n };\n }\n\n /**\n * Creates an RTCPeerConnection\n * @param {ClusterNode} clusterInfo information about the media cluster\n * @returns {RTCPeerConnection} peerConnection\n */\n private createPeerConnection(clusterInfo: ClusterNode) {\n try {\n const config = this.buildPeerConnectionConfig(clusterInfo);\n\n const peerConnection = new RTCPeerConnection(config);\n\n return peerConnection;\n } catch (peerConnectionError) {\n LoggerProxy.logger.warn(\n `Reachability:index#createPeerConnection --> Error creating peerConnection:`,\n peerConnectionError\n );\n\n return undefined;\n }\n }\n\n /**\n * @returns {ClusterReachabilityResult} reachability result for this cluster\n */\n getResult() {\n return this.result;\n }\n\n /**\n * Closes the peerConnection\n *\n * @returns {void}\n */\n private closePeerConnection() {\n if (this.pc) {\n this.pc.onicecandidate = null;\n this.pc.onicegatheringstatechange = null;\n this.pc.close();\n }\n }\n\n /**\n * Resolves the defer, indicating that reachability checks for this cluster are completed\n *\n * @returns {void}\n */\n private finishReachabilityCheck() {\n this.defer.resolve();\n }\n\n /**\n * Aborts the cluster reachability checks by closing the peer connection\n *\n * @returns {void}\n */\n public abort() {\n const {CLOSED} = CONNECTION_STATE;\n\n if (this.pc.connectionState !== CLOSED) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n }\n\n /**\n * Adds public IP (client media IPs)\n * @param {string} protocol\n * @param {string} publicIP\n * @returns {void}\n */\n private addPublicIP(protocol: 'udp' | 'tcp' | 'xtls', publicIP?: string | null) {\n const result = this.result[protocol];\n\n if (publicIP) {\n let ipAdded = false;\n\n if (result.clientMediaIPs) {\n if (!result.clientMediaIPs.includes(publicIP)) {\n result.clientMediaIPs.push(publicIP);\n ipAdded = true;\n }\n } else {\n result.clientMediaIPs = [publicIP];\n ipAdded = true;\n }\n\n if (ipAdded)\n this.emit(\n {\n file: 'clusterReachability',\n function: 'addPublicIP',\n },\n Events.clientMediaIpsUpdated,\n {\n protocol,\n clientMediaIPs: result.clientMediaIPs,\n }\n );\n }\n }\n\n /**\n * Registers a listener for the iceGatheringStateChange event\n *\n * @returns {void}\n */\n private registerIceGatheringStateChangeListener() {\n this.pc.onicegatheringstatechange = () => {\n if (this.pc.iceGatheringState === ICE_GATHERING_STATE.COMPLETE) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n };\n }\n\n /**\n * Saves the latency in the result for the given protocol and marks it as reachable,\n * emits the \"resultReady\" event if this is the first result for that protocol,\n * emits the \"clientMediaIpsUpdated\" event if we already had a result and only found\n * a new client IP\n *\n * @param {string} protocol\n * @param {number} latency\n * @param {string|null} [publicIp]\n * @param {string|null} [serverIp]\n * @returns {void}\n */\n private saveResult(\n protocol: 'udp' | 'tcp' | 'xtls',\n latency: number,\n publicIp?: string | null,\n serverIp?: string | null\n ) {\n const result = this.result[protocol];\n\n if (result.latencyInMilliseconds === undefined) {\n LoggerProxy.logger.log(\n // @ts-ignore\n `Reachability:index#saveResult --> Successfully reached ${this.name} over ${protocol}: ${latency}ms`\n );\n result.latencyInMilliseconds = latency;\n result.result = 'reachable';\n if (publicIp) {\n result.clientMediaIPs = [publicIp];\n }\n\n this.emit(\n {\n file: 'clusterReachability',\n function: 'saveResult',\n },\n Events.resultReady,\n {\n protocol,\n ...result,\n }\n );\n } else {\n this.addPublicIP(protocol, publicIp);\n }\n\n if (serverIp) {\n this.reachedSubnets.add(serverIp);\n }\n }\n\n /**\n * Determines NAT Type.\n *\n * @param {RTCIceCandidate} candidate\n * @returns {void}\n */\n private determineNatType(candidate: RTCIceCandidate) {\n this.srflxIceCandidates.push(candidate);\n\n if (this.srflxIceCandidates.length > 1) {\n const portsFound: Record<string, Set<number>> = {};\n\n this.srflxIceCandidates.forEach((c) => {\n const key = `${c.address}:${c.relatedPort}`;\n if (!portsFound[key]) {\n portsFound[key] = new Set();\n }\n portsFound[key].add(c.port);\n });\n\n Object.entries(portsFound).forEach(([, ports]) => {\n if (ports.size > 1) {\n // Found candidates with the same address and relatedPort, but different ports\n this.emit(\n {\n file: 'clusterReachability',\n function: 'determineNatType',\n },\n Events.natTypeUpdated,\n {\n natType: NatType.SymmetricNat,\n }\n );\n }\n });\n }\n }\n\n /**\n * Registers a listener for the icecandidate event\n *\n * @returns {void}\n */\n private registerIceCandidateListener() {\n this.pc.onicecandidate = (e) => {\n const TURN_TLS_PORT = 443;\n const CANDIDATE_TYPES = {\n SERVER_REFLEXIVE: 'srflx',\n RELAY: 'relay',\n };\n\n const latencyInMilliseconds = this.getElapsedTime();\n\n if (e.candidate) {\n if (e.candidate.type === CANDIDATE_TYPES.SERVER_REFLEXIVE) {\n let serverIp = null;\n if ('url' in e.candidate) {\n const stunServerUrlRegex = /stun:([\\d.]+):\\d+/;\n\n const match = (e.candidate as any).url.match(stunServerUrlRegex);\n if (match) {\n // eslint-disable-next-line prefer-destructuring\n serverIp = match[1];\n }\n }\n\n this.saveResult('udp', latencyInMilliseconds, e.candidate.address, serverIp);\n\n this.determineNatType(e.candidate);\n }\n\n if (e.candidate.type === CANDIDATE_TYPES.RELAY) {\n const protocol = e.candidate.port === TURN_TLS_PORT ? 'xtls' : 'tcp';\n this.saveResult(protocol, latencyInMilliseconds, null, e.candidate.address);\n }\n }\n };\n }\n\n /**\n * Starts the process of doing UDP and TCP reachability checks on the media cluster.\n * XTLS reachability checking is not supported.\n *\n * @returns {Promise}\n */\n async start(): Promise<ClusterReachabilityResult> {\n if (!this.pc) {\n LoggerProxy.logger.warn(\n `Reachability:ClusterReachability#start --> Error: peerConnection is undefined`\n );\n\n return this.result;\n }\n\n // Initialize this.result as saying that nothing is reachable.\n // It will get updated as we go along and successfully gather ICE candidates.\n this.result.udp = {\n result: this.numUdpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.tcp = {\n result: this.numTcpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.xtls = {\n result: this.numXTlsUrls > 0 ? 'unreachable' : 'untested',\n };\n\n try {\n const offer = await this.pc.createOffer({offerToReceiveAudio: true});\n\n this.startTimestamp = performance.now();\n\n // Set up the state change listeners before triggering the ICE gathering\n const gatherIceCandidatePromise = this.gatherIceCandidates();\n\n // not awaiting the next call on purpose, because we're not sending the offer anywhere and there won't be any answer\n // we just need to make this call to trigger the ICE gathering process\n this.pc.setLocalDescription(offer);\n\n await gatherIceCandidatePromise;\n } catch (error) {\n LoggerProxy.logger.warn(`Reachability:ClusterReachability#start --> Error: `, error);\n }\n\n return this.result;\n }\n\n /**\n * Starts the process of gathering ICE candidates\n *\n * @returns {Promise} promise that's resolved once reachability checks for this cluster are completed or timeout is reached\n */\n private gatherIceCandidates() {\n this.registerIceGatheringStateChangeListener();\n this.registerIceCandidateListener();\n\n return this.defer.promise;\n }\n}\n"],"mappings":"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"}
|
1
|
+
{"version":3,"names":["_common","require","_loggerProxy","_interopRequireDefault","_util","_eventsScope","_constants","_reachability","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","Events","exports","resultReady","clientMediaIpsUpdated","natTypeUpdated","ClusterReachability","_EventsScope","_inherits2","_super","name","clusterInfo","_this","_classCallCheck2","_assertThisInitialized2","_set","isVideoMesh","numUdpUrls","udp","numTcpUrls","tcp","numXTlsUrls","xtls","pc","createPeerConnection","defer","Defer","_createClass2","key","value","getElapsedTime","Math","round","performance","now","startTimestamp","buildPeerConnectionConfig","cluster","udpIceServers","map","url","username","credential","urls","tcpIceServers","urlString","convertStunUrlToTurn","turnTlsIceServers","convertStunUrlToTurnTls","iceServers","concat","_toConsumableArray2","iceCandidatePoolSize","iceTransportPolicy","config","peerConnection","RTCPeerConnection","peerConnectionError","LoggerProxy","logger","warn","undefined","getResult","closePeerConnection","onicecandidate","onicegatheringstatechange","close","finishReachabilityCheck","resolve","abort","CLOSED","CONNECTION_STATE","connectionState","addPublicIP","protocol","publicIP","ipAdded","clientMediaIPs","includes","emit","file","function","registerIceGatheringStateChangeListener","_this2","iceGatheringState","ICE_GATHERING_STATE","COMPLETE","saveResult","latency","publicIp","serverIp","latencyInMilliseconds","log","reachedSubnets","add","determineNatType","candidate","_this3","srflxIceCandidates","portsFound","c","address","relatedPort","port","_entries","_ref","_ref2","_slicedToArray2","ports","size","natType","NatType","SymmetricNat","registerIceCandidateListener","_this4","TURN_TLS_PORT","CANDIDATE_TYPES","SERVER_REFLEXIVE","RELAY","type","stunServerUrlRegex","match","_start","_asyncToGenerator2","_regenerator","mark","_callee","offer","gatherIceCandidatePromise","wrap","_callee$","_context","prev","next","abrupt","createOffer","offerToReceiveAudio","sent","gatherIceCandidates","setLocalDescription","t0","stop","start","promise","EventsScope"],"sources":["clusterReachability.ts"],"sourcesContent":["import {Defer} from '@webex/common';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ClusterNode} from './request';\nimport {convertStunUrlToTurn, convertStunUrlToTurnTls} from './util';\nimport EventsScope from '../common/events/events-scope';\n\nimport {CONNECTION_STATE, Enum, ICE_GATHERING_STATE} from '../constants';\nimport {ClusterReachabilityResult, NatType} from './reachability.types';\n\n// data for the Events.resultReady event\nexport type ResultEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n result: 'reachable' | 'unreachable' | 'untested';\n latencyInMilliseconds: number; // amount of time it took to get the ICE candidate\n clientMediaIPs?: string[];\n};\n\n// data for the Events.clientMediaIpsUpdated event\nexport type ClientMediaIpsUpdatedEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n clientMediaIPs: string[];\n};\n\nexport type NatTypeUpdatedEventData = {\n natType: NatType;\n};\n\nexport const Events = {\n resultReady: 'resultReady', // emitted when a cluster is reached successfully using specific protocol\n clientMediaIpsUpdated: 'clientMediaIpsUpdated', // emitted when more public IPs are found after resultReady was already sent for a given protocol\n natTypeUpdated: 'natTypeUpdated', // emitted when NAT type is determined\n} as const;\n\nexport type Events = Enum<typeof Events>;\n\n/**\n * A class that handles reachability checks for a single cluster.\n * It emits events from Events enum\n */\nexport class ClusterReachability extends EventsScope {\n private numUdpUrls: number;\n private numTcpUrls: number;\n private numXTlsUrls: number;\n private result: ClusterReachabilityResult;\n private pc?: RTCPeerConnection;\n private defer: Defer; // this defer is resolved once reachability checks for this cluster are completed\n private startTimestamp: number;\n private srflxIceCandidates: RTCIceCandidate[] = [];\n public readonly isVideoMesh: boolean;\n public readonly name;\n public readonly reachedSubnets: Set<string> = new Set();\n\n /**\n * Constructor for ClusterReachability\n * @param {string} name cluster name\n * @param {ClusterNode} clusterInfo information about the media cluster\n */\n constructor(name: string, clusterInfo: ClusterNode) {\n super();\n this.name = name;\n this.isVideoMesh = clusterInfo.isVideoMesh;\n this.numUdpUrls = clusterInfo.udp.length;\n this.numTcpUrls = clusterInfo.tcp.length;\n this.numXTlsUrls = clusterInfo.xtls.length;\n\n this.pc = this.createPeerConnection(clusterInfo);\n\n this.defer = new Defer();\n this.result = {\n udp: {\n result: 'untested',\n },\n tcp: {\n result: 'untested',\n },\n xtls: {\n result: 'untested',\n },\n };\n }\n\n /**\n * Gets total elapsed time, can be called only after start() is called\n * @returns {Number} Milliseconds\n */\n private getElapsedTime() {\n return Math.round(performance.now() - this.startTimestamp);\n }\n\n /**\n * Generate peerConnection config settings\n * @param {ClusterNode} cluster\n * @returns {RTCConfiguration} peerConnectionConfig\n */\n private buildPeerConnectionConfig(cluster: ClusterNode): RTCConfiguration {\n const udpIceServers = cluster.udp.map((url) => ({\n username: '',\n credential: '',\n urls: [url],\n }));\n\n // STUN servers are contacted only using UDP, so in order to test TCP reachability\n // we pretend that Linus is a TURN server, because we can explicitly say \"transport=tcp\" in TURN urls.\n // We then check for relay candidates to know if TURN-TCP worked (see registerIceCandidateListener()).\n const tcpIceServers = cluster.tcp.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurn(urlString, 'tcp')],\n };\n });\n\n const turnTlsIceServers = cluster.xtls.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurnTls(urlString)],\n };\n });\n\n return {\n iceServers: [...udpIceServers, ...tcpIceServers, ...turnTlsIceServers],\n iceCandidatePoolSize: 0,\n iceTransportPolicy: 'all',\n };\n }\n\n /**\n * Creates an RTCPeerConnection\n * @param {ClusterNode} clusterInfo information about the media cluster\n * @returns {RTCPeerConnection} peerConnection\n */\n private createPeerConnection(clusterInfo: ClusterNode) {\n try {\n const config = this.buildPeerConnectionConfig(clusterInfo);\n\n const peerConnection = new RTCPeerConnection(config);\n\n return peerConnection;\n } catch (peerConnectionError) {\n LoggerProxy.logger.warn(\n `Reachability:index#createPeerConnection --> Error creating peerConnection:`,\n peerConnectionError\n );\n\n return undefined;\n }\n }\n\n /**\n * @returns {ClusterReachabilityResult} reachability result for this cluster\n */\n getResult() {\n return this.result;\n }\n\n /**\n * Closes the peerConnection\n *\n * @returns {void}\n */\n private closePeerConnection() {\n if (this.pc) {\n this.pc.onicecandidate = null;\n this.pc.onicegatheringstatechange = null;\n this.pc.close();\n }\n this.pc = null;\n }\n\n /**\n * Resolves the defer, indicating that reachability checks for this cluster are completed\n *\n * @returns {void}\n */\n private finishReachabilityCheck() {\n this.defer.resolve();\n }\n\n /**\n * Aborts the cluster reachability checks by closing the peer connection\n *\n * @returns {void}\n */\n public abort() {\n const {CLOSED} = CONNECTION_STATE;\n\n if (this.pc.connectionState !== CLOSED) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n }\n\n /**\n * Adds public IP (client media IPs)\n * @param {string} protocol\n * @param {string} publicIP\n * @returns {void}\n */\n private addPublicIP(protocol: 'udp' | 'tcp' | 'xtls', publicIP?: string | null) {\n const result = this.result[protocol];\n\n if (publicIP) {\n let ipAdded = false;\n\n if (result.clientMediaIPs) {\n if (!result.clientMediaIPs.includes(publicIP)) {\n result.clientMediaIPs.push(publicIP);\n ipAdded = true;\n }\n } else {\n result.clientMediaIPs = [publicIP];\n ipAdded = true;\n }\n\n if (ipAdded)\n this.emit(\n {\n file: 'clusterReachability',\n function: 'addPublicIP',\n },\n Events.clientMediaIpsUpdated,\n {\n protocol,\n clientMediaIPs: result.clientMediaIPs,\n }\n );\n }\n }\n\n /**\n * Registers a listener for the iceGatheringStateChange event\n *\n * @returns {void}\n */\n private registerIceGatheringStateChangeListener() {\n this.pc.onicegatheringstatechange = () => {\n if (this.pc.iceGatheringState === ICE_GATHERING_STATE.COMPLETE) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n };\n }\n\n /**\n * Saves the latency in the result for the given protocol and marks it as reachable,\n * emits the \"resultReady\" event if this is the first result for that protocol,\n * emits the \"clientMediaIpsUpdated\" event if we already had a result and only found\n * a new client IP\n *\n * @param {string} protocol\n * @param {number} latency\n * @param {string|null} [publicIp]\n * @param {string|null} [serverIp]\n * @returns {void}\n */\n private saveResult(\n protocol: 'udp' | 'tcp' | 'xtls',\n latency: number,\n publicIp?: string | null,\n serverIp?: string | null\n ) {\n const result = this.result[protocol];\n\n if (result.latencyInMilliseconds === undefined) {\n LoggerProxy.logger.log(\n // @ts-ignore\n `Reachability:index#saveResult --> Successfully reached ${this.name} over ${protocol}: ${latency}ms`\n );\n result.latencyInMilliseconds = latency;\n result.result = 'reachable';\n if (publicIp) {\n result.clientMediaIPs = [publicIp];\n }\n\n this.emit(\n {\n file: 'clusterReachability',\n function: 'saveResult',\n },\n Events.resultReady,\n {\n protocol,\n ...result,\n }\n );\n } else {\n this.addPublicIP(protocol, publicIp);\n }\n\n if (serverIp) {\n this.reachedSubnets.add(serverIp);\n }\n }\n\n /**\n * Determines NAT Type.\n *\n * @param {RTCIceCandidate} candidate\n * @returns {void}\n */\n private determineNatType(candidate: RTCIceCandidate) {\n this.srflxIceCandidates.push(candidate);\n\n if (this.srflxIceCandidates.length > 1) {\n const portsFound: Record<string, Set<number>> = {};\n\n this.srflxIceCandidates.forEach((c) => {\n const key = `${c.address}:${c.relatedPort}`;\n if (!portsFound[key]) {\n portsFound[key] = new Set();\n }\n portsFound[key].add(c.port);\n });\n\n Object.entries(portsFound).forEach(([, ports]) => {\n if (ports.size > 1) {\n // Found candidates with the same address and relatedPort, but different ports\n this.emit(\n {\n file: 'clusterReachability',\n function: 'determineNatType',\n },\n Events.natTypeUpdated,\n {\n natType: NatType.SymmetricNat,\n }\n );\n }\n });\n }\n }\n\n /**\n * Registers a listener for the icecandidate event\n *\n * @returns {void}\n */\n private registerIceCandidateListener() {\n this.pc.onicecandidate = (e) => {\n const TURN_TLS_PORT = 443;\n const CANDIDATE_TYPES = {\n SERVER_REFLEXIVE: 'srflx',\n RELAY: 'relay',\n };\n\n const latencyInMilliseconds = this.getElapsedTime();\n\n if (e.candidate) {\n if (e.candidate.type === CANDIDATE_TYPES.SERVER_REFLEXIVE) {\n let serverIp = null;\n if ('url' in e.candidate) {\n const stunServerUrlRegex = /stun:([\\d.]+):\\d+/;\n\n const match = (e.candidate as any).url.match(stunServerUrlRegex);\n if (match) {\n // eslint-disable-next-line prefer-destructuring\n serverIp = match[1];\n }\n }\n\n this.saveResult('udp', latencyInMilliseconds, e.candidate.address, serverIp);\n\n this.determineNatType(e.candidate);\n }\n\n if (e.candidate.type === CANDIDATE_TYPES.RELAY) {\n const protocol = e.candidate.port === TURN_TLS_PORT ? 'xtls' : 'tcp';\n this.saveResult(protocol, latencyInMilliseconds, null, e.candidate.address);\n }\n }\n };\n }\n\n /**\n * Starts the process of doing UDP and TCP reachability checks on the media cluster.\n * XTLS reachability checking is not supported.\n *\n * @returns {Promise}\n */\n async start(): Promise<ClusterReachabilityResult> {\n if (!this.pc) {\n LoggerProxy.logger.warn(\n `Reachability:ClusterReachability#start --> Error: peerConnection is undefined`\n );\n\n return this.result;\n }\n\n // Initialize this.result as saying that nothing is reachable.\n // It will get updated as we go along and successfully gather ICE candidates.\n this.result.udp = {\n result: this.numUdpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.tcp = {\n result: this.numTcpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.xtls = {\n result: this.numXTlsUrls > 0 ? 'unreachable' : 'untested',\n };\n\n try {\n const offer = await this.pc.createOffer({offerToReceiveAudio: true});\n\n this.startTimestamp = performance.now();\n\n // Set up the state change listeners before triggering the ICE gathering\n const gatherIceCandidatePromise = this.gatherIceCandidates();\n\n // not awaiting the next call on purpose, because we're not sending the offer anywhere and there won't be any answer\n // we just need to make this call to trigger the ICE gathering process\n this.pc.setLocalDescription(offer);\n\n await gatherIceCandidatePromise;\n } catch (error) {\n LoggerProxy.logger.warn(`Reachability:ClusterReachability#start --> Error: `, error);\n }\n\n return this.result;\n }\n\n /**\n * Starts the process of gathering ICE candidates\n *\n * @returns {Promise} promise that's resolved once reachability checks for this cluster are completed or timeout is reached\n */\n private gatherIceCandidates() {\n this.registerIceGatheringStateChangeListener();\n this.registerIceCandidateListener();\n\n return this.defer.promise;\n }\n}\n"],"mappings":"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"}
|
package/dist/types/config.d.ts
CHANGED
@@ -236,6 +236,16 @@ export default class Meetings extends WebexPlugin {
|
|
236
236
|
* @returns {undefined}
|
237
237
|
*/
|
238
238
|
private _toggleDisableAudioMainDtx;
|
239
|
+
/**
|
240
|
+
* API to toggle stopping ICE Candidates Gathering after first relay candidate,
|
241
|
+
* needs to be called before webex.meetings.joinWithMedia()
|
242
|
+
*
|
243
|
+
* @param {Boolean} newValue
|
244
|
+
* @private
|
245
|
+
* @memberof Meetings
|
246
|
+
* @returns {undefined}
|
247
|
+
*/
|
248
|
+
private _toggleStopIceGatheringAfterFirstRelayCandidate;
|
239
249
|
/**
|
240
250
|
* Executes a registration step and updates the registration status.
|
241
251
|
* @param {Function} step - The registration step to execute.
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
@@ -43,7 +43,7 @@
|
|
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.8.0-next.
|
46
|
+
"@webex/plugin-meetings": "3.8.0-next.67",
|
47
47
|
"@webex/plugin-rooms": "3.8.0-next.23",
|
48
48
|
"@webex/test-helper-chai": "3.8.0-next.19",
|
49
49
|
"@webex/test-helper-mocha": "3.8.0-next.19",
|
@@ -71,7 +71,7 @@
|
|
71
71
|
"@webex/internal-plugin-metrics": "3.8.0-next.19",
|
72
72
|
"@webex/internal-plugin-support": "3.8.0-next.23",
|
73
73
|
"@webex/internal-plugin-user": "3.8.0-next.19",
|
74
|
-
"@webex/internal-plugin-voicea": "3.8.0-next.
|
74
|
+
"@webex/internal-plugin-voicea": "3.8.0-next.67",
|
75
75
|
"@webex/media-helpers": "3.8.0-next.23",
|
76
76
|
"@webex/plugin-people": "3.8.0-next.21",
|
77
77
|
"@webex/plugin-rooms": "3.8.0-next.23",
|
@@ -93,5 +93,5 @@
|
|
93
93
|
"//": [
|
94
94
|
"TODO: upgrade jwt-decode when moving to node 18"
|
95
95
|
],
|
96
|
-
"version": "3.8.0-next.
|
96
|
+
"version": "3.8.0-next.67"
|
97
97
|
}
|
package/src/config.ts
CHANGED
@@ -98,5 +98,6 @@ export default {
|
|
98
98
|
enableReachabilityChecks: true,
|
99
99
|
reachabilityGetClusterTimeout: 5000,
|
100
100
|
logUploadIntervalMultiplicationFactor: 0, // if set to 0 or undefined, logs won't be uploaded periodically, if you want periodic logs, recommended value is 1
|
101
|
+
stopIceGatheringAfterFirstRelayCandidate: false,
|
101
102
|
},
|
102
103
|
};
|
package/src/media/index.ts
CHANGED
@@ -16,6 +16,7 @@ import {
|
|
16
16
|
LocalMicrophoneStream,
|
17
17
|
} from '@webex/media-helpers';
|
18
18
|
import {RtcMetrics} from '@webex/internal-plugin-metrics';
|
19
|
+
import {BrowserInfo} from '@webex/web-capabilities';
|
19
20
|
import LoggerProxy from '../common/logs/logger-proxy';
|
20
21
|
import {MEDIA_TRACK_CONSTRAINT} from '../constants';
|
21
22
|
import Config from '../config';
|
@@ -143,6 +144,7 @@ Media.createMediaConnection = (
|
|
143
144
|
bundlePolicy?: BundlePolicy;
|
144
145
|
iceCandidatesTimeout?: number;
|
145
146
|
disableAudioMainDtx?: boolean;
|
147
|
+
stopIceGatheringAfterFirstRelayCandidate?: boolean;
|
146
148
|
}
|
147
149
|
) => {
|
148
150
|
const {
|
@@ -155,6 +157,7 @@ Media.createMediaConnection = (
|
|
155
157
|
bundlePolicy,
|
156
158
|
iceCandidatesTimeout,
|
157
159
|
disableAudioMainDtx,
|
160
|
+
stopIceGatheringAfterFirstRelayCandidate,
|
158
161
|
} = options;
|
159
162
|
|
160
163
|
const iceServers = [];
|
@@ -182,6 +185,12 @@ Media.createMediaConnection = (
|
|
182
185
|
config.disableAudioMainDtx = disableAudioMainDtx;
|
183
186
|
}
|
184
187
|
|
188
|
+
if (BrowserInfo.isFirefox()) {
|
189
|
+
config.doFullIce = true;
|
190
|
+
|
191
|
+
config.stopIceGatheringAfterFirstRelayCandidate = stopIceGatheringAfterFirstRelayCandidate;
|
192
|
+
}
|
193
|
+
|
185
194
|
return new MultistreamRoapMediaConnection(
|
186
195
|
config,
|
187
196
|
meetingId,
|
package/src/meeting/index.ts
CHANGED
@@ -7022,6 +7022,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7022
7022
|
iceCandidatesTimeout: this.config.iceCandidatesGatheringTimeout,
|
7023
7023
|
// @ts-ignore - config coming from registerPlugin
|
7024
7024
|
disableAudioMainDtx: this.config.experimental.disableAudioMainDtx,
|
7025
|
+
stopIceGatheringAfterFirstRelayCandidate:
|
7026
|
+
// @ts-ignore - config coming from registerPlugin
|
7027
|
+
this.config.stopIceGatheringAfterFirstRelayCandidate,
|
7025
7028
|
}
|
7026
7029
|
);
|
7027
7030
|
|
package/src/meetings/index.ts
CHANGED
@@ -827,6 +827,27 @@ export default class Meetings extends WebexPlugin {
|
|
827
827
|
}
|
828
828
|
}
|
829
829
|
|
830
|
+
/**
|
831
|
+
* API to toggle stopping ICE Candidates Gathering after first relay candidate,
|
832
|
+
* needs to be called before webex.meetings.joinWithMedia()
|
833
|
+
*
|
834
|
+
* @param {Boolean} newValue
|
835
|
+
* @private
|
836
|
+
* @memberof Meetings
|
837
|
+
* @returns {undefined}
|
838
|
+
*/
|
839
|
+
private _toggleStopIceGatheringAfterFirstRelayCandidate(newValue: boolean) {
|
840
|
+
if (typeof newValue !== 'boolean') {
|
841
|
+
return;
|
842
|
+
}
|
843
|
+
|
844
|
+
// @ts-ignore
|
845
|
+
if (this.config.stopIceGatheringAfterFirstRelayCandidate !== newValue) {
|
846
|
+
// @ts-ignore
|
847
|
+
this.config.stopIceGatheringAfterFirstRelayCandidate = newValue;
|
848
|
+
}
|
849
|
+
}
|
850
|
+
|
830
851
|
/**
|
831
852
|
* Executes a registration step and updates the registration status.
|
832
853
|
* @param {Function} step - The registration step to execute.
|
@@ -4,6 +4,7 @@ import Media from '@webex/plugin-meetings/src/media/index';
|
|
4
4
|
import {assert} from '@webex/test-helper-chai';
|
5
5
|
import sinon from 'sinon';
|
6
6
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
7
|
+
import { BrowserInfo } from '@webex/web-capabilities';
|
7
8
|
|
8
9
|
describe('createMediaConnection', () => {
|
9
10
|
let clock;
|
@@ -197,7 +198,68 @@ describe('createMediaConnection', () => {
|
|
197
198
|
|
198
199
|
sendMetricsInQueueCallback();
|
199
200
|
assert.calledOnce(rtcMetrics.sendMetricsInQueue);
|
201
|
+
});
|
202
|
+
|
203
|
+
it('multistream non-firefox does not care about stopIceGatheringAfterFirstRelayCandidate', () => {
|
204
|
+
const multistreamRoapMediaConnectionConstructorStub = sinon
|
205
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
206
|
+
.returns(fakeRoapMediaConnection);
|
207
|
+
|
208
|
+
Media.createMediaConnection(true, 'some debug id', 'meeting id', {
|
209
|
+
stopIceGatheringAfterFirstRelayCandidate: true,
|
210
|
+
});
|
211
|
+
assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
|
212
|
+
assert.calledWith(
|
213
|
+
multistreamRoapMediaConnectionConstructorStub,
|
214
|
+
{
|
215
|
+
iceServers: []
|
216
|
+
},
|
217
|
+
'meeting id'
|
218
|
+
);
|
219
|
+
});
|
220
|
+
|
221
|
+
it('multistream firefox stops gathering after first relay if stopIceGatheringAfterFirstRelayCandidate is true', () => {
|
222
|
+
const multistreamRoapMediaConnectionConstructorStub = sinon
|
223
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
224
|
+
.returns(fakeRoapMediaConnection);
|
225
|
+
|
226
|
+
sinon.stub(BrowserInfo, 'isFirefox').returns(true);
|
227
|
+
|
228
|
+
Media.createMediaConnection(true, 'some debug id', 'meeting id', {
|
229
|
+
stopIceGatheringAfterFirstRelayCandidate: true,
|
230
|
+
});
|
231
|
+
assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
|
232
|
+
assert.calledWith(
|
233
|
+
multistreamRoapMediaConnectionConstructorStub,
|
234
|
+
{
|
235
|
+
iceServers: [],
|
236
|
+
doFullIce: true,
|
237
|
+
stopIceGatheringAfterFirstRelayCandidate: true,
|
238
|
+
},
|
239
|
+
'meeting id'
|
240
|
+
);
|
241
|
+
});
|
242
|
+
|
243
|
+
it('multistream firefox continues gathering if stopIceGatheringAfterFirstRelayCandidate is false', () => {
|
244
|
+
const multistreamRoapMediaConnectionConstructorStub = sinon
|
245
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
246
|
+
.returns(fakeRoapMediaConnection);
|
247
|
+
|
248
|
+
sinon.stub(BrowserInfo, 'isFirefox').returns(true);
|
200
249
|
|
250
|
+
Media.createMediaConnection(true, 'some debug id', 'meeting id', {
|
251
|
+
stopIceGatheringAfterFirstRelayCandidate: false,
|
252
|
+
});
|
253
|
+
assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
|
254
|
+
assert.calledWith(
|
255
|
+
multistreamRoapMediaConnectionConstructorStub,
|
256
|
+
{
|
257
|
+
iceServers: [],
|
258
|
+
doFullIce: true,
|
259
|
+
stopIceGatheringAfterFirstRelayCandidate: false,
|
260
|
+
},
|
261
|
+
'meeting id'
|
262
|
+
);
|
201
263
|
});
|
202
264
|
|
203
265
|
[
|
@@ -413,6 +413,19 @@ describe('plugin-meetings', () => {
|
|
413
413
|
});
|
414
414
|
});
|
415
415
|
|
416
|
+
describe('#_toggleStopIceGatheringAfterFirstRelayCandidate', () => {
|
417
|
+
it('should have _toggleStopIceGatheringAfterFirstRelayCandidate', () => {
|
418
|
+
assert.equal(typeof webex.meetings._toggleStopIceGatheringAfterFirstRelayCandidate, 'function');
|
419
|
+
});
|
420
|
+
|
421
|
+
describe('success', () => {
|
422
|
+
it('should update meetings to stop ICE candidates gathering after first relay candidate', () => {
|
423
|
+
webex.meetings._toggleStopIceGatheringAfterFirstRelayCandidate(true);
|
424
|
+
assert.equal(webex.meetings.config.stopIceGatheringAfterFirstRelayCandidate, true);
|
425
|
+
});
|
426
|
+
});
|
427
|
+
});
|
428
|
+
|
416
429
|
describe('Public API Contracts', () => {
|
417
430
|
describe('#register', () => {
|
418
431
|
it('emits an event and resolves when register succeeds', async () => {
|