123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /* global __filename */
- import { getLogger } from 'jitsi-meet-logger';
-
- import * as JitsiConferenceErrors from '../../JitsiConferenceErrors';
- import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
-
- import { default as networkInfo, NETWORK_INFO_EVENT } from './NetworkInfo';
-
- const logger = getLogger(__filename);
-
- /**
- * Helper class for handling ICE event delay in combination with internet online/offline status check.
- */
- class DelayedIceFailedEvent {
- /**
- * A constructor.
- * @param {function} emitIceFailed - Will be called by this class to emit ICE failed conference event.
- * @param {number} delay - The delay for ICE failed in milliseconds since the event occurred on the peerconnection
- * or the internet came back online.
- */
- constructor(emitIceFailed, delay) {
- this._emitIceFailed = emitIceFailed;
- this._delay = delay;
- }
-
- /**
- * Starts the event delay and internet status check logic.
- */
- start() {
- this._onlineListener
- = networkInfo.addEventListener(
- NETWORK_INFO_EVENT,
- () => this._maybeSetDelayTimeout());
- this._maybeSetDelayTimeout();
- }
-
- /**
- * Cancels the task.
- */
- stop() {
- this._onlineListener && this._onlineListener();
- this._onlineListener = undefined;
- clearTimeout(this._delayTimeout);
- }
-
- /**
- * Resets the timer delay if the internet status is online.
- * @private
- */
- _maybeSetDelayTimeout() {
- clearTimeout(this._delayTimeout);
-
- if (networkInfo.isOnline()) {
- logger.info(`Will emit ICE failed in ${this._delay}ms`);
- this._delayTimeout = setTimeout(() => this._emitIceFailed(), this._delay);
- }
- }
- }
-
-
- /**
- * This class deals with shenanigans around JVB media session's ICE failed status handling.
- *
- * If ICE restarts are NOT explicitly enabled by the {@code enableIceRestart} config option, then the conference will
- * delay emitting the {@JitsiConferenceErrors.ICE_FAILED} event by 15 seconds. If the network info module reports
- * the internet offline status then the time will start counting after the internet comes back online.
- *
- * If ICE restart are enabled, then a delayed ICE failed notification to Jicofo will be sent, only if the ICE connection
- * does not recover soon after or before the XMPP connection is restored (if it was ever broken). If ICE fails while
- * the XMPP connection is not broken then the notifications will be sent after 2 seconds delay.
- */
- export default class IceFailedHandling {
- /**
- * Creates new {@code DelayedIceFailed} task.
- * @param {JitsiConference} conference
- */
- constructor(conference) {
- this._conference = conference;
- }
-
- /**
- * Starts the task.
- */
- start() {
- if (!this._conference.options.config.enableIceRestart) {
- logger.info('ICE failed, but ICE restarts are disabled');
- this._delayedIceFailedEvent = new DelayedIceFailedEvent(() => {
- this._conference.eventEmitter.emit(
- JitsiConferenceEvents.CONFERENCE_FAILED,
- JitsiConferenceErrors.ICE_FAILED);
- }, 15000);
- this._delayedIceFailedEvent.start();
-
- return;
- } else if (!this._conference.xmpp.isPingSupported()) {
- // Let Jicofo know that the JVB's ICE connection has failed
- logger.info('PING not supported - sending ICE failed notification immediately');
- this._conference.jvbJingleSession.sendIceFailedNotification();
-
- return;
- }
-
- // The 65 seconds are greater than the default Prosody's BOSH
- // timeout of 60. This gives some time for the XMPP connection
- // to recover.
- this._conference.xmpp.ping(65000).then(
- () => {
- if (this._canceled) {
- return;
- }
-
- const jvbConnection = this._conference.jvbJingleSession;
- const jvbConnIceState = jvbConnection && jvbConnection.getIceConnectionState();
-
- if (!jvbConnection) {
- logger.warn('Not sending ICE failed - no JVB connection');
- } else if (jvbConnIceState === 'connected') {
- logger.info('ICE connection restored - not sending ICE failed');
- } else {
- this._iceFailedTimeout = window.setTimeout(() => {
- logger.info(`Sending ICE failed - the connection has not recovered: ${jvbConnIceState}`);
- this._iceFailedTimeout = undefined;
- jvbConnection.sendIceFailedNotification();
- }, 2000);
- }
- },
- error => {
- logger.error('PING error/timeout - not sending ICE failed', error);
- });
- }
-
- /**
- * Cancels the task.
- */
- cancel() {
- this._canceled = true;
- window.clearTimeout(this._iceFailedTimeout);
- this._delayedIceFailedEvent && this._delayedIceFailedEvent.stop();
- }
- }
|