浏览代码

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 6 年前
父节点
当前提交
2e1436e20d
共有 2 个文件被更改,包括 79 次插入2 次删除
  1. 13
    2
      JitsiConference.js
  2. 66
    0
      modules/connectivity/IceFailedNotification.js

+ 13
- 2
JitsiConference.js 查看文件

19
 import TalkMutedDetection from './modules/TalkMutedDetection';
19
 import TalkMutedDetection from './modules/TalkMutedDetection';
20
 import browser from './modules/browser';
20
 import browser from './modules/browser';
21
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
21
 import ConnectionQuality from './modules/connectivity/ConnectionQuality';
22
+import IceFailedNotification
23
+    from './modules/connectivity/IceFailedNotification';
22
 import ParticipantConnectionStatusHandler
24
 import ParticipantConnectionStatusHandler
23
     from './modules/connectivity/ParticipantConnectionStatus';
25
     from './modules/connectivity/ParticipantConnectionStatus';
24
 import E2ePing from './modules/e2eping/e2eping';
26
 import E2ePing from './modules/e2eping/e2eping';
434
         this.statistics.dispose();
436
         this.statistics.dispose();
435
     }
437
     }
436
 
438
 
439
+    this._delayedIceFailed && this._delayedIceFailed.cancel();
440
+
437
     // Close both JVb and P2P JingleSessions
441
     // Close both JVb and P2P JingleSessions
438
     if (this.jvbJingleSession) {
442
     if (this.jvbJingleSession) {
439
         this.jvbJingleSession.close();
443
         this.jvbJingleSession.close();
2365
         }
2369
         }
2366
         this._stopP2PSession('connectivity-error', 'ICE FAILED');
2370
         this._stopP2PSession('connectivity-error', 'ICE FAILED');
2367
     } else if (session && this.jvbJingleSession === session) {
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
         this.isP2PConnectionInterrupted = false;
2390
         this.isP2PConnectionInterrupted = false;
2381
     } else {
2391
     } else {
2382
         this.isJvbConnectionInterrupted = false;
2392
         this.isJvbConnectionInterrupted = false;
2393
+        this._delayedIceFailed && this._delayedIceFailed.cancel();
2383
     }
2394
     }
2384
 
2395
 
2385
     if (session.isP2P === this.isP2PActive()) {
2396
     if (session.isP2P === this.isP2PActive()) {

+ 66
- 0
modules/connectivity/IceFailedNotification.js 查看文件

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
+}

正在加载...
取消
保存