Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

IceFailedHandling.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* global __filename */
  2. import { getLogger } from 'jitsi-meet-logger';
  3. import * as JitsiConferenceErrors from '../../JitsiConferenceErrors';
  4. import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
  5. import { default as networkInfo, NETWORK_INFO_EVENT } from './NetworkInfo';
  6. const logger = getLogger(__filename);
  7. /**
  8. * Helper class for handling ICE event delay in combination with internet online/offline status check.
  9. */
  10. class DelayedIceFailedEvent {
  11. /**
  12. * A constructor.
  13. * @param {function} emitIceFailed - Will be called by this class to emit ICE failed conference event.
  14. * @param {number} delay - The delay for ICE failed in milliseconds since the event occurred on the peerconnection
  15. * or the internet came back online.
  16. */
  17. constructor(emitIceFailed, delay) {
  18. this._emitIceFailed = emitIceFailed;
  19. this._delay = delay;
  20. }
  21. /**
  22. * Starts the event delay and internet status check logic.
  23. */
  24. start() {
  25. this._onlineListener
  26. = networkInfo.addEventListener(
  27. NETWORK_INFO_EVENT,
  28. () => this._maybeSetDelayTimeout());
  29. this._maybeSetDelayTimeout();
  30. }
  31. /**
  32. * Cancels the task.
  33. */
  34. stop() {
  35. this._onlineListener && this._onlineListener();
  36. this._onlineListener = undefined;
  37. clearTimeout(this._delayTimeout);
  38. }
  39. /**
  40. * Resets the timer delay if the internet status is online.
  41. * @private
  42. */
  43. _maybeSetDelayTimeout() {
  44. clearTimeout(this._delayTimeout);
  45. if (networkInfo.isOnline()) {
  46. logger.info(`Will emit ICE failed in ${this._delay}ms`);
  47. this._delayTimeout = setTimeout(() => this._emitIceFailed(), this._delay);
  48. }
  49. }
  50. }
  51. /**
  52. * This class deals with shenanigans around JVB media session's ICE failed status handling.
  53. *
  54. * If ICE restarts are NOT explicitly enabled by the {@code enableIceRestart} config option, then the conference will
  55. * delay emitting the {@JitsiConferenceErrors.ICE_FAILED} event by 15 seconds. If the network info module reports
  56. * the internet offline status then the time will start counting after the internet comes back online.
  57. *
  58. * If ICE restart are enabled, then a delayed ICE failed notification to Jicofo will be sent, only if the ICE connection
  59. * does not recover soon after or before the XMPP connection is restored (if it was ever broken). If ICE fails while
  60. * the XMPP connection is not broken then the notifications will be sent after 2 seconds delay.
  61. */
  62. export default class IceFailedHandling {
  63. /**
  64. * Creates new {@code DelayedIceFailed} task.
  65. * @param {JitsiConference} conference
  66. */
  67. constructor(conference) {
  68. this._conference = conference;
  69. }
  70. /**
  71. * Starts the task.
  72. */
  73. start() {
  74. if (!this._conference.options.config.enableIceRestart) {
  75. logger.info('ICE failed, but ICE restarts are disabled');
  76. this._delayedIceFailedEvent = new DelayedIceFailedEvent(() => {
  77. this._conference.eventEmitter.emit(
  78. JitsiConferenceEvents.CONFERENCE_FAILED,
  79. JitsiConferenceErrors.ICE_FAILED);
  80. }, 15000);
  81. this._delayedIceFailedEvent.start();
  82. return;
  83. } else if (!this._conference.xmpp.isPingSupported()) {
  84. // Let Jicofo know that the JVB's ICE connection has failed
  85. logger.info('PING not supported - sending ICE failed notification immediately');
  86. this._conference.jvbJingleSession.sendIceFailedNotification();
  87. return;
  88. }
  89. // The 65 seconds are greater than the default Prosody's BOSH
  90. // timeout of 60. This gives some time for the XMPP connection
  91. // to recover.
  92. this._conference.xmpp.ping(65000).then(
  93. () => {
  94. if (this._canceled) {
  95. return;
  96. }
  97. const jvbConnection = this._conference.jvbJingleSession;
  98. const jvbConnIceState = jvbConnection && jvbConnection.getIceConnectionState();
  99. if (!jvbConnection) {
  100. logger.warn('Not sending ICE failed - no JVB connection');
  101. } else if (jvbConnIceState === 'connected') {
  102. logger.info('ICE connection restored - not sending ICE failed');
  103. } else {
  104. this._iceFailedTimeout = window.setTimeout(() => {
  105. logger.info(`Sending ICE failed - the connection has not recovered: ${jvbConnIceState}`);
  106. this._iceFailedTimeout = undefined;
  107. jvbConnection.sendIceFailedNotification();
  108. }, 2000);
  109. }
  110. },
  111. error => {
  112. logger.error('PING error/timeout - not sending ICE failed', error);
  113. });
  114. }
  115. /**
  116. * Cancels the task.
  117. */
  118. cancel() {
  119. this._canceled = true;
  120. window.clearTimeout(this._iceFailedTimeout);
  121. this._delayedIceFailedEvent && this._delayedIceFailedEvent.stop();
  122. }
  123. }