Bläddra i källkod

Implements fault tolerant connect (closes #268).

j8
George Politis 10 år sedan
förälder
incheckning
e0cba855a6
4 ändrade filer med 27633 tillägg och 27331 borttagningar
  1. 1
    1
      index.html
  2. 27506
    27274
      libs/app.bundle.js
  3. 124
    55
      modules/xmpp/xmpp.js
  4. 2
    1
      package.json

+ 1
- 1
index.html Visa fil

@@ -19,7 +19,7 @@
19 19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20 20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21 21
     <script src="interface_config.js?v=5"></script>
22
-    <script src="libs/app.bundle.js?v=62"></script>
22
+    <script src="libs/app.bundle.js?v=63"></script>
23 23
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24 24
     <link rel="stylesheet" href="css/font.css?v=7"/>
25 25
     <link rel="stylesheet" href="css/toastr.css?v=1">

+ 27506
- 27274
libs/app.bundle.js
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 124
- 55
modules/xmpp/xmpp.js Visa fil

@@ -9,76 +9,145 @@ var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
9 9
 var RTCEvents = require("../../service/RTC/RTCEvents");
10 10
 var UIEvents = require("../../service/UI/UIEvents");
11 11
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
12
+var retry = require('retry');
12 13
 
13 14
 var eventEmitter = new EventEmitter();
14 15
 var connection = null;
15 16
 var authenticatedUser = false;
16 17
 
17 18
 function connect(jid, password) {
18
-    connection = XMPP.createConnection();
19
-    Moderator.setConnection(connection);
20 19
 
21
-    if (connection.disco) {
22
-        // for chrome, add multistream cap
23
-    }
24
-    connection.jingle.pc_constraints = APP.RTC.getPCConstraints();
25
-    if (config.useIPv6) {
26
-        // https://code.google.com/p/webrtc/issues/detail?id=2828
27
-        if (!connection.jingle.pc_constraints.optional)
28
-            connection.jingle.pc_constraints.optional = [];
29
-        connection.jingle.pc_constraints.optional.push({googIPv6: true});
30
-    }
20
+    var faultTolerantConnect = retry.operation({
21
+        retries: 3
22
+    });
31 23
 
32
-    // Include user info in MUC presence
33
-    var settings = Settings.getSettings();
34
-    if (settings.email) {
35
-        connection.emuc.addEmailToPresence(settings.email);
36
-    }
37
-    if (settings.uid) {
38
-        connection.emuc.addUserIdToPresence(settings.uid);
39
-    }
40
-    if (settings.displayName) {
41
-        connection.emuc.addDisplayNameToPresence(settings.displayName);
42
-    }
24
+    // fault tolerant connect
25
+    faultTolerantConnect.attempt(function () {
43 26
 
44
-    var anonymousConnectionFailed = false;
45
-    var wasConnected = false;
46
-    var lastErrorMsg;
47
-    connection.connect(jid, password, function (status, msg) {
48
-        console.log('Strophe status changed to',
49
-            Strophe.getStatusString(status), msg);
50
-        if (status === Strophe.Status.CONNECTED) {
27
+        connection = XMPP.createConnection();
28
+        Moderator.setConnection(connection);
51 29
 
52
-            wasConnected = true;
30
+        if (connection.disco) {
31
+            // for chrome, add multistream cap
32
+        }
33
+        connection.jingle.pc_constraints = APP.RTC.getPCConstraints();
34
+        if (config.useIPv6) {
35
+            // https://code.google.com/p/webrtc/issues/detail?id=2828
36
+            if (!connection.jingle.pc_constraints.optional)
37
+                connection.jingle.pc_constraints.optional = [];
38
+            connection.jingle.pc_constraints.optional.push({googIPv6: true});
39
+        }
53 40
 
54
-            if (config.useStunTurn) {
55
-                connection.jingle.getStunAndTurnCredentials();
56
-            }
41
+        // Include user info in MUC presence
42
+        var settings = Settings.getSettings();
43
+        if (settings.email) {
44
+            connection.emuc.addEmailToPresence(settings.email);
45
+        }
46
+        if (settings.uid) {
47
+            connection.emuc.addUserIdToPresence(settings.uid);
48
+        }
49
+        if (settings.displayName) {
50
+            connection.emuc.addDisplayNameToPresence(settings.displayName);
51
+        }
57 52
 
58
-            console.info("My Jabber ID: " + connection.jid);
59 53
 
60
-            if (password)
61
-                authenticatedUser = true;
62
-            maybeDoJoin();
63
-        } else if (status === Strophe.Status.CONNFAIL) {
64
-            if (msg === 'x-strophe-bad-non-anon-jid') {
65
-                anonymousConnectionFailed = true;
66
-            }
67
-            lastErrorMsg = msg;
68
-        } else if (status === Strophe.Status.DISCONNECTED) {
69
-            if (anonymousConnectionFailed) {
70
-                // prompt user for username and password
54
+        // connection.connect() starts the connection process.
55
+        //
56
+        // As the connection process proceeds, the user supplied callback will
57
+        // be triggered multiple times with status updates. The callback should
58
+        // take two arguments - the status code and the error condition.
59
+        //
60
+        // The status code will be one of the values in the Strophe.Status
61
+        // constants. The error condition will be one of the conditions defined
62
+        // in RFC 3920 or the condition ‘strophe-parsererror’.
63
+        //
64
+        // The Parameters wait, hold and route are optional and only relevant
65
+        // for BOSH connections. Please see XEP 124 for a more detailed
66
+        // explanation of the optional parameters.
67
+        //
68
+        // Connection status constants for use by the connection handler
69
+        // callback.
70
+        //
71
+        //  Status.ERROR - An error has occurred (websockets specific)
72
+        //  Status.CONNECTING - The connection is currently being made
73
+        //  Status.CONNFAIL - The connection attempt failed
74
+        //  Status.AUTHENTICATING - The connection is authenticating
75
+        //  Status.AUTHFAIL - The authentication attempt failed
76
+        //  Status.CONNECTED - The connection has succeeded
77
+        //  Status.DISCONNECTED - The connection has been terminated
78
+        //  Status.DISCONNECTING - The connection is currently being terminated
79
+        //  Status.ATTACHED - The connection has been attached
80
+
81
+        var anonymousConnectionFailed = false;
82
+        var connectionFailed = false;
83
+        var lastErrorMsg;
84
+        connection.connect(jid, password, function (status, msg) {
85
+            console.log('Strophe status changed to',
86
+                Strophe.getStatusString(status), msg);
87
+            if (status === Strophe.Status.CONNECTED) {
88
+                if (config.useStunTurn) {
89
+                    connection.jingle.getStunAndTurnCredentials();
90
+                }
91
+
92
+                console.info("My Jabber ID: " + connection.jid);
93
+
94
+                if (password)
95
+                    authenticatedUser = true;
96
+                maybeDoJoin();
97
+            } else if (status === Strophe.Status.CONNFAIL) {
98
+                if (msg === 'x-strophe-bad-non-anon-jid') {
99
+                    anonymousConnectionFailed = true;
100
+                } else {
101
+                    connectionFailed = true;
102
+                }
103
+                lastErrorMsg = msg;
104
+            } else if (status === Strophe.Status.DISCONNECTED) {
105
+                if (anonymousConnectionFailed) {
106
+                    // prompt user for username and password
107
+                    XMPP.promptLogin();
108
+                } else {
109
+
110
+                    // Strophe already has built-in HTTP/BOSH error handling and
111
+                    // request retry logic. Requests are resent automatically
112
+                    // until their error count reaches 5. Strophe.js disconnects
113
+                    // if the error count is > 5. We are not replicating this
114
+                    // here.
115
+                    //
116
+                    // The "problem" is that failed HTTP/BOSH requests don't
117
+                    // trigger a callback with a status update, so when a
118
+                    // callback with status Strophe.Status.DISCONNECTED arrives,
119
+                    // we can't be sure if it's a graceful disconnect or if it's
120
+                    // triggered by some HTTP/BOSH error.
121
+                    //
122
+                    // But that's a minor issue in Jitsi Meet as we never
123
+                    // disconnect anyway, not even when the user closes the
124
+                    // browser window (which is kind of wrong, but the point is
125
+                    // that we should never ever get disconnected).
126
+                    //
127
+                    // On the other hand, failed connections due to XMPP layer
128
+                    // errors, trigger a callback with status Strophe.Status.CONNFAIL.
129
+                    //
130
+                    // Here we implement retry logic for failed connections due
131
+                    // to XMPP layer errors and we display an error to the user
132
+                    // if we get disconnected from the XMPP server permanently.
133
+
134
+                    // If the connection failed, retry.
135
+                    if (connectionFailed
136
+                        && faultTolerantConnect.retry("connection-failed")) {
137
+                        return;
138
+                    }
139
+
140
+                    // If we failed to connect to the XMPP server, fire an event
141
+                    // to let all the interested module now about it.
142
+                    eventEmitter.emit(XMPPEvents.CONNECTION_FAILED,
143
+                        msg ? msg : lastErrorMsg);
144
+                }
145
+            } else if (status === Strophe.Status.AUTHFAIL) {
146
+                // wrong password or username, prompt user
71 147
                 XMPP.promptLogin();
72
-            } else if (!wasConnected) {
73
-                eventEmitter.emit(
74
-                    XMPPEvents.CONNECTION_FAILED,
75
-                    msg ? msg : lastErrorMsg);
76
-            }
77
-        } else if (status === Strophe.Status.AUTHFAIL) {
78
-            // wrong password or username, prompt user
79
-            XMPP.promptLogin();
80 148
 
81
-        }
149
+            }
150
+        });
82 151
     });
83 152
 }
84 153
 

+ 2
- 1
package.json Visa fil

@@ -20,7 +20,8 @@
20 20
       "i18next-client": "1.7.7",
21 21
       "sdp-interop": "jitsi/sdp-interop#f65fedfe57a",
22 22
       "sdp-transform": "1.3.0",
23
-      "async": "0.9.0"
23
+      "async": "0.9.0",
24
+      "retry": "0.6.1"
24 25
   },
25 26
   "devDependencies": {
26 27
   },

Laddar…
Avbryt
Spara