Parcourir la source

feat(JitsiConference): delay the ICE failed notification

Because it's possible to go back from ICE FAILED state to CONNECTED it's
better to give it some time until the XMPP connection recovers and only
if they ICE does not recover in time send the ICE failed notification
to Jicofo. It's done by sending a ping to the XMPP server and checking
the ICE after 2 seconds past the ping successful response.
dev1
paweldomas il y a 6 ans
Parent
révision
2e1436e20d
2 fichiers modifiés avec 79 ajouts et 2 suppressions
  1. 13
    2
      JitsiConference.js
  2. 66
    0
      modules/connectivity/IceFailedNotification.js

+ 13
- 2
JitsiConference.js Voir le fichier

@@ -19,6 +19,8 @@ import RTC from './modules/RTC/RTC';
19 19
 import TalkMutedDetection from './modules/TalkMutedDetection';
20 20
 import browser from './modules/browser';
21 21
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
22
+import IceFailedNotification
23
+    from './modules/connectivity/IceFailedNotification';
22 24
 import ParticipantConnectionStatusHandler
23 25
     from './modules/connectivity/ParticipantConnectionStatus';
24 26
 import E2ePing from './modules/e2eping/e2eping';
@@ -434,6 +436,8 @@ JitsiConference.prototype.leave = function() {
434 436
         this.statistics.dispose();
435 437
     }
436 438
 
439
+    this._delayedIceFailed && this._delayedIceFailed.cancel();
440
+
437 441
     // Close both JVb and P2P JingleSessions
438 442
     if (this.jvbJingleSession) {
439 443
         this.jvbJingleSession.close();
@@ -2365,8 +2369,14 @@ JitsiConference.prototype._onIceConnectionFailed = function(session) {
2365 2369
         }
2366 2370
         this._stopP2PSession('connectivity-error', 'ICE FAILED');
2367 2371
     } else if (session && this.jvbJingleSession === session) {
2368
-        // Let Jicofo know that the JVB's ICE connection has failed
2369
-        session.sendIceFailedNotification();
2372
+        if (this.xmpp.isPingSupported()) {
2373
+            this._delayedIceFailed = new IceFailedNotification(this);
2374
+            this._delayedIceFailed.start(session);
2375
+        } else {
2376
+            // Let Jicofo know that the JVB's ICE connection has failed
2377
+            logger.info('PING not supported - sending ICE failed immediately');
2378
+            session.sendIceFailedNotification();
2379
+        }
2370 2380
     }
2371 2381
 };
2372 2382
 
@@ -2380,6 +2390,7 @@ JitsiConference.prototype._onIceConnectionRestored = function(session) {
2380 2390
         this.isP2PConnectionInterrupted = false;
2381 2391
     } else {
2382 2392
         this.isJvbConnectionInterrupted = false;
2393
+        this._delayedIceFailed && this._delayedIceFailed.cancel();
2383 2394
     }
2384 2395
 
2385 2396
     if (session.isP2P === this.isP2PActive()) {

+ 66
- 0
modules/connectivity/IceFailedNotification.js Voir le fichier

@@ -0,0 +1,66 @@
1
+/* global __filename */
2
+import { getLogger } from 'jitsi-meet-logger';
3
+
4
+const logger = getLogger(__filename);
5
+
6
+/**
7
+ * A delayed ICE failed notification which is triggered only if the ICE
8
+ * connection does not recover soon after or before the XMPP connection is
9
+ * restored (if it was ever broken). If ICE fails while the XMPP connection is
10
+ * not broken then the notifications will be sent after 2 seconds delay. This
11
+ * extra delay is not intentional just a side effect of the code.
12
+ * NOTE that this delayed task can only be used if PING is supported by the XMPP
13
+ * server.
14
+ */
15
+export default class IceFailedNotification {
16
+    /**
17
+     * Creates new {@code DelayedIceFailed} task.
18
+     * @param {JitsiConference} conference
19
+     */
20
+    constructor(conference) {
21
+        this._conference = conference;
22
+    }
23
+
24
+    /**
25
+     * Starts the task.
26
+     * @param {JingleSessionPC} session - the JVB Jingle session.
27
+     */
28
+    start(session) {
29
+        // The 65 seconds are greater than the default Prosody's BOSH
30
+        // timeout of 60. This gives some time for the XMPP connection
31
+        // to recover.
32
+        this._conference.xmpp.ping(65000).then(
33
+            () => {
34
+                if (this._canceled) {
35
+                    return;
36
+                }
37
+
38
+                if (this._conference.isJvbConnectionInterrupted) {
39
+                    this._iceFailedTimeout = window.setTimeout(() => {
40
+                        logger.info(
41
+                            'Sending ICE failed'
42
+                            + ' - the connection has not recovered');
43
+                        this._iceFailedTimeout = undefined;
44
+                        session.sendIceFailedNotification();
45
+                    }, 2000);
46
+                } else {
47
+                    logger.info(
48
+                        'ICE connection restored - not sending ICE failed');
49
+                }
50
+            },
51
+            error => {
52
+                logger.error(
53
+                    'PING error/timeout - not sending ICE failed', error);
54
+            });
55
+    }
56
+
57
+    /**
58
+     * Cancels the task.
59
+     */
60
+    cancel() {
61
+        this._canceled = true;
62
+        if (this._iceFailedTimeout) {
63
+            window.clearTimeout(this._iceFailedTimeout);
64
+        }
65
+    }
66
+}

Chargement…
Annuler
Enregistrer