소스 검색

feat(XmppConnection) add WebSocket keep alive

Websocket keep alive is HTTP GET request sent on the service URL passed
to Strophe. It is used to keep the stick tables alive. The feature comes
in enabled by default whenever Websocket are used. Pass
'websocketKeepAlive' config option set to -1 to disable.

See the code for more details about the default interval value.
release-8443
paweldomas 5 년 전
부모
커밋
aceb20b9af
2개의 변경된 파일53개의 추가작업 그리고 7개의 파일을 삭제
  1. 44
    2
      modules/xmpp/XmppConnection.js
  2. 9
    5
      modules/xmpp/xmpp.js

+ 44
- 2
modules/xmpp/XmppConnection.js 파일 보기

@@ -38,10 +38,17 @@ export default class XmppConnection extends Listenable {
38 38
      * @param {Object} options
39 39
      * @param {String} options.serviceUrl - The BOSH or WebSocket service URL.
40 40
      * @param {String} options.enableWebsocketResume - True to enable stream resumption.
41
+     * @param {Number} [options.websocketKeepAlive=240000] - The websocket keep alive interval. It's 4 minutes by
42
+     * default with jitter. Pass -1 to disable. The actual interval equation is:
43
+     * jitterDelay = (interval * 0.2) + (0.8 * interval * Math.random())
44
+     * The keep alive is HTTP GET request to the {@link options.serviceUrl}.
41 45
      */
42
-    constructor({ enableWebsocketResume, serviceUrl }) {
46
+    constructor({ enableWebsocketResume, websocketKeepAlive, serviceUrl }) {
43 47
         super();
44
-        this._options = { enableWebsocketResume };
48
+        this._options = {
49
+            enableWebsocketResume,
50
+            websocketKeepAlive: typeof websocketKeepAlive === 'undefined' ? 4 * 60 * 1000 : Number(websocketKeepAlive)
51
+        };
45 52
         this._stropheConn = new Strophe.Connection(serviceUrl);
46 53
         this._usesWebsocket = serviceUrl.startsWith('ws:') || serviceUrl.startsWith('wss:');
47 54
 
@@ -218,9 +225,13 @@ export default class XmppConnection extends Listenable {
218 225
 
219 226
             if (status === Strophe.Status.CONNECTED) {
220 227
                 this._maybeEnableStreamResume();
228
+                this._maybeStartWSKeepAlive();
221 229
             } else if (status === Strophe.Status.DISCONNECTED) {
222 230
                 // FIXME add RECONNECTING state instead of blocking the DISCONNECTED update
223 231
                 blockCallback = this._tryResumingConnection();
232
+                if (!blockCallback) {
233
+                    clearTimeout(this._wsKeepAlive);
234
+                }
224 235
             }
225 236
 
226 237
             if (!blockCallback) {
@@ -248,6 +259,7 @@ export default class XmppConnection extends Listenable {
248 259
      */
249 260
     disconnect(...args) {
250 261
         clearTimeout(this._resumeTimeout);
262
+        clearTimeout(this._wsKeepAlive);
251 263
         this._stropheConn.disconnect(...args);
252 264
     }
253 265
 
@@ -296,6 +308,36 @@ export default class XmppConnection extends Listenable {
296 308
         }
297 309
     }
298 310
 
311
+    /**
312
+     * Starts the Websocket keep alive if enabled.
313
+     *
314
+     * @private
315
+     * @returns {void}
316
+     */
317
+    _maybeStartWSKeepAlive() {
318
+        const { websocketKeepAlive } = this._options;
319
+
320
+        if (this._usesWebsocket && websocketKeepAlive > 0) {
321
+            this._wsKeepAlive || logger.info(`WebSocket keep alive interval: ${websocketKeepAlive}ms`);
322
+            clearTimeout(this._wsKeepAlive);
323
+
324
+            const intervalWithJitter
325
+                = /* base */ (websocketKeepAlive * 0.2) + /* jitter */ (Math.random() * 0.8 * websocketKeepAlive);
326
+
327
+            logger.debug(`Scheduling next WebSocket keep-alive in ${intervalWithJitter}ms`);
328
+
329
+            this._wsKeepAlive = setTimeout(() => {
330
+                const url = this.service.replace('wss', 'https').replace('ws', 'http');
331
+
332
+                fetch(url).catch(
333
+                    error => {
334
+                        logger.error(`Websocket Keep alive failed for url: ${url}`, { error });
335
+                    })
336
+                    .then(() => this._maybeStartWSKeepAlive());
337
+            }, intervalWithJitter);
338
+        }
339
+    }
340
+
299 341
     /**
300 342
      * Send a stanza. This function is called to push data onto the send queue to go out over the wire.
301 343
      *

+ 9
- 5
modules/xmpp/xmpp.js 파일 보기

@@ -30,9 +30,10 @@ const logger = getLogger(__filename);
30 30
  * Prosody).
31 31
  * @param {string} options.serviceUrl - The service URL for XMPP connection.
32 32
  * @param {string} options.enableWebsocketResume - True to enable stream resumption.
33
+ * @param {number} [options.websocketKeepAlive] - See {@link XmppConnection} constructor.
33 34
  * @returns {XmppConnection}
34 35
  */
35
-function createConnection({ enableWebsocketResume, serviceUrl = '/http-bind', token }) {
36
+function createConnection({ enableWebsocketResume, serviceUrl = '/http-bind', token, websocketKeepAlive }) {
36 37
     // Append token as URL param
37 38
     if (token) {
38 39
         // eslint-disable-next-line no-param-reassign
@@ -41,7 +42,8 @@ function createConnection({ enableWebsocketResume, serviceUrl = '/http-bind', to
41 42
 
42 43
     return new XmppConnection({
43 44
         enableWebsocketResume,
44
-        serviceUrl
45
+        serviceUrl,
46
+        websocketKeepAlive
45 47
     });
46 48
 }
47 49
 
@@ -86,8 +88,9 @@ export default class XMPP extends Listenable {
86 88
      * @param {String} options.bosh - Deprecated, use {@code serviceUrl}.
87 89
      * @param {boolean} options.enableWebsocketResume - Enables XEP-0198 stream management which will make the XMPP
88 90
      * module try to resume the session in case the Websocket connection breaks.
89
-     * @param {Array<Object>} options.p2pStunServers see
90
-     * {@link JingleConnectionPlugin} for more details.
91
+     * @param {number} [options.websocketKeepAlive] - The websocket keep alive interval. See {@link XmppConnection}
92
+     * constructor for more details.
93
+     * @param {Array<Object>} options.p2pStunServers see {@link JingleConnectionPlugin} for more details.
91 94
      * @param token
92 95
      */
93 96
     constructor(options, token) {
@@ -106,7 +109,8 @@ export default class XMPP extends Listenable {
106 109
 
107 110
             // FIXME remove deprecated bosh option at some point
108 111
             serviceUrl: options.serviceUrl || options.bosh,
109
-            token
112
+            token,
113
+            websocketKeepAlive: options.websocketKeepAlive
110 114
         });
111 115
 
112 116
         this._initStrophePlugins();

Loading…
취소
저장