|
@@ -3,6 +3,7 @@ import { $pres, Strophe } from 'strophe.js';
|
3
|
3
|
import 'strophejs-plugin-stream-management';
|
4
|
4
|
|
5
|
5
|
import Listenable from '../util/Listenable';
|
|
6
|
+import { getJitterDelay } from '../util/Retry';
|
6
|
7
|
|
7
|
8
|
import LastSuccessTracker from './StropheBoshLastSuccess';
|
8
|
9
|
|
|
@@ -50,6 +51,13 @@ export default class XmppConnection extends Listenable {
|
50
|
51
|
enableWebsocketResume: typeof enableWebsocketResume === 'undefined' ? true : enableWebsocketResume,
|
51
|
52
|
websocketKeepAlive: typeof websocketKeepAlive === 'undefined' ? 4 * 60 * 1000 : Number(websocketKeepAlive)
|
52
|
53
|
};
|
|
54
|
+
|
|
55
|
+ /**
|
|
56
|
+ * The counter increased before each resume retry attempt, used to calculate exponential backoff.
|
|
57
|
+ * @type {number}
|
|
58
|
+ * @private
|
|
59
|
+ */
|
|
60
|
+ this._resumeRetryN = 0;
|
53
|
61
|
this._stropheConn = new Strophe.Connection(serviceUrl);
|
54
|
62
|
this._usesWebsocket = serviceUrl.startsWith('ws:') || serviceUrl.startsWith('wss:');
|
55
|
63
|
|
|
@@ -206,6 +214,7 @@ export default class XmppConnection extends Listenable {
|
206
|
214
|
if (status === Strophe.Status.CONNECTED) {
|
207
|
215
|
this._maybeEnableStreamResume();
|
208
|
216
|
this._maybeStartWSKeepAlive();
|
|
217
|
+ this._resumeRetryN = 0;
|
209
|
218
|
} else if (status === Strophe.Status.DISCONNECTED) {
|
210
|
219
|
// FIXME add RECONNECTING state instead of blocking the DISCONNECTED update
|
211
|
220
|
blockCallback = this._tryResumingConnection();
|
|
@@ -421,6 +430,17 @@ export default class XmppConnection extends Listenable {
|
421
|
430
|
|
422
|
431
|
if (resumeToken) {
|
423
|
432
|
clearTimeout(this._resumeTimeout);
|
|
433
|
+
|
|
434
|
+ // FIXME detect internet offline
|
|
435
|
+ // The retry delay will be:
|
|
436
|
+ // 1st retry: 1.5s - 3s
|
|
437
|
+ // 2nd retry: 3s - 9s
|
|
438
|
+ // 3rd retry: 3s - 27s
|
|
439
|
+ this._resumeRetryN = Math.min(3, this._resumeRetryN + 1);
|
|
440
|
+ const retryTimeout = getJitterDelay(this._resumeRetryN, 1500, 3);
|
|
441
|
+
|
|
442
|
+ logger.info(`Will try to resume the XMPP connection in ${retryTimeout}ms`);
|
|
443
|
+
|
424
|
444
|
this._resumeTimeout = setTimeout(() => {
|
425
|
445
|
logger.info('Trying to resume the XMPP connection');
|
426
|
446
|
|
|
@@ -428,11 +448,10 @@ export default class XmppConnection extends Listenable {
|
428
|
448
|
|
429
|
449
|
url.searchParams.set('previd', resumeToken);
|
430
|
450
|
|
431
|
|
- // FIXME remove XmppConnection 'service' setter
|
432
|
451
|
this._stropheConn.service = url.toString();
|
433
|
452
|
|
434
|
453
|
streamManagement.resume();
|
435
|
|
- }, 3000 /* FIXME calculate delay with jitter */);
|
|
454
|
+ }, retryTimeout);
|
436
|
455
|
|
437
|
456
|
return true;
|
438
|
457
|
}
|