|
@@ -522,69 +522,75 @@ export default class XMPP extends Listenable {
|
522
|
522
|
|
523
|
523
|
this.eventEmitter.on(XMPPEvents.CONNECTION_STATUS_CHANGED, disconnectListener);
|
524
|
524
|
|
525
|
|
- // XXX Strophe is asynchronously sending by default. Unfortunately, that
|
526
|
|
- // means that there may not be enough time to send an unavailable
|
527
|
|
- // presence or disconnect at all. Switching Strophe to synchronous
|
528
|
|
- // sending is not much of an option because it may lead to a noticeable
|
529
|
|
- // delay in navigating away from the current location. As a compromise,
|
530
|
|
- // we will try to increase the chances of sending an unavailable
|
531
|
|
- // presence and/or disconecting within the short time span that we have
|
532
|
|
- // upon unloading by invoking flush() on the connection. We flush() once
|
533
|
|
- // before disconnect() in order to attemtp to have its unavailable
|
534
|
|
- // presence at the top of the send queue. We flush() once more after
|
535
|
|
- // disconnect() in order to attempt to have its unavailable presence
|
536
|
|
- // sent as soon as possible.
|
537
|
|
- this.connection.flush();
|
|
525
|
+ this._cleanupXmppConnection(ev);
|
|
526
|
+ });
|
|
527
|
+ }
|
538
|
528
|
|
539
|
|
- if (ev !== null && typeof ev !== 'undefined') {
|
540
|
|
- const evType = ev.type;
|
541
|
|
-
|
542
|
|
- if (evType === 'beforeunload' || evType === 'unload') {
|
543
|
|
- // XXX Whatever we said above, synchronous sending is the best
|
544
|
|
- // (known) way to properly disconnect from the XMPP server.
|
545
|
|
- // Consequently, it may be fine to have the source code and
|
546
|
|
- // comment it in or out depending on whether we want to run with
|
547
|
|
- // it for some time.
|
548
|
|
- this.connection.options.sync = true;
|
549
|
|
-
|
550
|
|
- // This is needed in some browsers where sync xhr sending
|
551
|
|
- // is disabled by default on unload
|
552
|
|
- if (navigator.sendBeacon && !this.connection.disconnecting
|
553
|
|
- && this.connection.connected) {
|
554
|
|
- this.connection._changeConnectStatus(Strophe.Status.DISCONNECTING);
|
555
|
|
- this.connection.disconnecting = true;
|
556
|
|
-
|
557
|
|
- const body = this.connection._proto._buildBody()
|
558
|
|
- .attrs({
|
559
|
|
- type: 'terminate'
|
560
|
|
- });
|
561
|
|
- const pres = $pres({
|
562
|
|
- xmlns: Strophe.NS.CLIENT,
|
563
|
|
- type: 'unavailable'
|
|
529
|
+ /**
|
|
530
|
+ * The method is supposed to gracefully close the XMPP connection and the main goal is to make sure that the current
|
|
531
|
+ * participant will be removed from the conference XMPP MUC, so that it doesn't leave a "ghost" participant behind.
|
|
532
|
+ *
|
|
533
|
+ * @param {Object} ev - Optionally, the event which triggered the necessity to disconnect from the XMPP server
|
|
534
|
+ * (e.g. beforeunload, unload).
|
|
535
|
+ * @private
|
|
536
|
+ * @returns {void}
|
|
537
|
+ */
|
|
538
|
+ _cleanupXmppConnection(ev) {
|
|
539
|
+ // XXX Strophe is asynchronously sending by default. Unfortunately, that means that there may not be enough time
|
|
540
|
+ // to send an unavailable presence or disconnect at all. Switching Strophe to synchronous sending is not much of
|
|
541
|
+ // an option because it may lead to a noticeable delay in navigating away from the current location. As
|
|
542
|
+ // a compromise, we will try to increase the chances of sending an unavailable presence and/or disconnecting
|
|
543
|
+ // within the short time span that we have upon unloading by invoking flush() on the connection. We flush() once
|
|
544
|
+ // before disconnect() in order to attempt to have its unavailable presence at the top of the send queue. We
|
|
545
|
+ // flush() once more after disconnect() in order to attempt to have its unavailable presence sent as soon as
|
|
546
|
+ // possible.
|
|
547
|
+ this.connection.flush();
|
|
548
|
+
|
|
549
|
+ if (ev !== null && typeof ev !== 'undefined') {
|
|
550
|
+ const evType = ev.type;
|
|
551
|
+
|
|
552
|
+ if (evType === 'beforeunload' || evType === 'unload') {
|
|
553
|
+ // XXX Whatever we said above, synchronous sending is the best (known) way to properly disconnect from
|
|
554
|
+ // the XMPP server. Consequently, it may be fine to have the source code and comment it in or out
|
|
555
|
+ // depending on whether we want to run with it for some time.
|
|
556
|
+ this.connection.options.sync = true;
|
|
557
|
+
|
|
558
|
+ // This is needed in some browsers where sync xhr sending is disabled by default on unload.
|
|
559
|
+ if (navigator.sendBeacon && !this.connection.disconnecting && this.connection.connected) {
|
|
560
|
+
|
|
561
|
+ this.connection._changeConnectStatus(Strophe.Status.DISCONNECTING);
|
|
562
|
+ this.connection.disconnecting = true;
|
|
563
|
+
|
|
564
|
+ const body = this.connection._proto._buildBody()
|
|
565
|
+ .attrs({
|
|
566
|
+ type: 'terminate'
|
564
|
567
|
});
|
|
568
|
+ const pres = $pres({
|
|
569
|
+ xmlns: Strophe.NS.CLIENT,
|
|
570
|
+ type: 'unavailable'
|
|
571
|
+ });
|
565
|
572
|
|
566
|
|
- body.cnode(pres.tree());
|
|
573
|
+ body.cnode(pres.tree());
|
567
|
574
|
|
568
|
|
- const res = navigator.sendBeacon(
|
569
|
|
- `https:${this.connection.service}`,
|
570
|
|
- Strophe.serialize(body.tree()));
|
|
575
|
+ const res = navigator.sendBeacon(
|
|
576
|
+ `https:${this.connection.service}`,
|
|
577
|
+ Strophe.serialize(body.tree()));
|
571
|
578
|
|
572
|
|
- logger.info(`Successfully send unavailable beacon ${res}`);
|
|
579
|
+ logger.info(`Successfully send unavailable beacon ${res}`);
|
573
|
580
|
|
574
|
|
- this.connection._proto._abortAllRequests();
|
575
|
|
- this.connection._doDisconnect();
|
|
581
|
+ this.connection._proto._abortAllRequests();
|
|
582
|
+ this.connection._doDisconnect();
|
576
|
583
|
|
577
|
|
- return;
|
578
|
|
- }
|
|
584
|
+ return;
|
579
|
585
|
}
|
580
|
586
|
}
|
|
587
|
+ }
|
581
|
588
|
|
582
|
|
- this.connection.disconnect();
|
|
589
|
+ this.connection.disconnect();
|
583
|
590
|
|
584
|
|
- if (this.connection.options.sync !== true) {
|
585
|
|
- this.connection.flush();
|
586
|
|
- }
|
587
|
|
- });
|
|
591
|
+ if (this.connection.options.sync !== true) {
|
|
592
|
+ this.connection.flush();
|
|
593
|
+ }
|
588
|
594
|
}
|
589
|
595
|
|
590
|
596
|
/**
|