@@ -82,6 +82,15 @@ interface IInternalOptions {
8282 websocketKeepAliveUrl ?: string ;
8383}
8484
85+ const TOKEN_REFRESH = 'token_refresh' ;
86+
87+ /**
88+ * Adds one more status to Strophe.Status enum.
89+ */
90+ enum ExtendedStatus {
91+ RESUMING = 15
92+ }
93+
8594/**
8695 * The lib-jitsi-meet layer for {@link Strophe.Connection}.
8796 * @internal
@@ -128,7 +137,7 @@ export default class XmppConnection extends Listenable {
128137 * @returns {Strophe.Status }
129138 */
130139 static get Status ( ) {
131- return Strophe . Status ;
140+ return { ... Strophe . Status , ... ExtendedStatus } ;
132141 }
133142
134143 /**
@@ -395,8 +404,6 @@ export default class XmppConnection extends Listenable {
395404 _stropheConnectionCb ( targetCallback : IConnectionStatusCallback , status : Strophe . Status , condition ?: string , element ?: Element ) : void {
396405 this . _status = status ;
397406
398- let blockCallback = false ;
399-
400407 if ( status === Strophe . Status . CONNECTED || status === Strophe . Status . ATTACHED ) {
401408 this . _maybeEnableStreamResume ( ) ;
402409
@@ -421,17 +428,24 @@ export default class XmppConnection extends Listenable {
421428 } else if ( status === Strophe . Status . DISCONNECTED ) {
422429 this . ping . stopInterval ( ) ;
423430
424- // FIXME add RECONNECTING state instead of blocking the DISCONNECTED update
425- blockCallback = this . _tryResumingConnection ( ) ;
426- if ( ! blockCallback ) {
427- clearTimeout ( this . _wsKeepAlive ) ;
431+ // if resumption is scheduled skip disconnecting state event fire
432+ if ( this . _tryResumingConnection ( condition === TOKEN_REFRESH ) ) {
433+
434+ if ( condition !== TOKEN_REFRESH ) {
435+ // let's fire event that status changed to resuming
436+ // we do not fire it on refresh, as consumers should get
437+ // the event and execute refresh with a new token
438+ this . eventEmitter . emit ( XmppConnection . Events . CONN_STATUS_CHANGED , ExtendedStatus . RESUMING ) ;
439+ }
440+
441+ return ;
428442 }
429- }
430443
431- if ( ! blockCallback ) {
432- targetCallback ( status , condition , element ) ;
433- this . eventEmitter . emit ( XmppConnection . Events . CONN_STATUS_CHANGED , status ) ;
444+ clearTimeout ( this . _wsKeepAlive ) ;
434445 }
446+
447+ targetCallback ( status , condition , element ) ;
448+ this . eventEmitter . emit ( XmppConnection . Events . CONN_STATUS_CHANGED , status ) ;
435449 }
436450
437451 /**
@@ -758,14 +772,22 @@ export default class XmppConnection extends Listenable {
758772 * the token is present it means the connection can be resumed.
759773 *
760774 * @private
761- * @returns {boolean }
775+ * @returns {boolean } - Whether a resume attempt was scheduled or executed.
762776 */
763- _tryResumingConnection ( ) : boolean {
777+ _tryResumingConnection ( force = false ) : boolean {
764778 const { streamManagement } = this . _stropheConn ;
765779 const resumeToken = streamManagement ?. getResumeToken ( ) ;
766780
767781 if ( resumeToken ) {
768- this . _resumeTask . schedule ( ) ;
782+ if ( force ) {
783+ logger . info ( 'Trying to resume XMPP connection immediately due to token refresh' ) ;
784+
785+ this . _resumeTask . resumeConnection ( ) ;
786+
787+ return true ;
788+ } else {
789+ this . _resumeTask . schedule ( ) ;
790+ }
769791
770792 const r = this . _resumeTask . retryCount <= MAX_CONNECTION_RETRIES ;
771793
@@ -778,4 +800,34 @@ export default class XmppConnection extends Listenable {
778800
779801 return false ;
780802 }
803+
804+ /**
805+ * This method allows renewal of the tokens if they are expiring.
806+ * @param token - The new token.
807+ */
808+ refreshToken ( serviceUrl : string ) : Promise < void > {
809+ this . _stropheConn . service = serviceUrl ;
810+
811+ // this will trigger a resume
812+ this . _stropheConn . _doDisconnect ( TOKEN_REFRESH ) ;
813+
814+ return new Promise ( ( resolve , reject ) => {
815+ const handler = status => {
816+ if ( status === Strophe . Status . CONNECTED && this . _stropheConn . restored ) {
817+ resolve ( ) ;
818+ }
819+ } ;
820+
821+ this . addCancellableListener ( XmppConnection . Events . CONN_STATUS_CHANGED , handler ) ;
822+
823+ setTimeout ( ( ) => {
824+ this . removeListener ( XmppConnection . Events . CONN_STATUS_CHANGED , handler ) ;
825+ reject ( ) ;
826+ } , 3000 ) ;
827+ } ) ;
828+ }
829+
830+ cancelResume ( ) {
831+ this . _resumeTask . cancelResume ( ) ;
832+ }
781833}
0 commit comments