Browse Source

feat: Handles conferenceIQ error with redirect.

<iq id='some-id' from='focus.exmaple.com' type='error' xml:lang='en-US' to='some-jid' xmlns='jabber:client'>
    <error type='modify'>
        <redirect xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        <conference xmlns='http://jitsi.org/protocol/focus' vnode='v1' main-room='roomtest@conference.focus.exmaple.com' focusjid='focus@auth.meet.jitsi'/>
    </error>
</iq>
tags/v0.0.2
damencho 2 years ago
parent
commit
271cce2f62

+ 4
- 1
JitsiConferenceErrors.spec.ts View File

22
         OFFER_ANSWER_FAILED,
22
         OFFER_ANSWER_FAILED,
23
         PASSWORD_NOT_SUPPORTED,
23
         PASSWORD_NOT_SUPPORTED,
24
         PASSWORD_REQUIRED,
24
         PASSWORD_REQUIRED,
25
+        REDIRECTED,
25
         RESERVATION_ERROR,
26
         RESERVATION_ERROR,
26
         VIDEOBRIDGE_NOT_AVAILABLE,
27
         VIDEOBRIDGE_NOT_AVAILABLE,
27
         JitsiConferenceErrors,
28
         JitsiConferenceErrors,
48
         expect( PASSWORD_NOT_SUPPORTED ).toBe( 'conference.passwordNotSupported' );
49
         expect( PASSWORD_NOT_SUPPORTED ).toBe( 'conference.passwordNotSupported' );
49
         expect( PASSWORD_REQUIRED ).toBe( 'conference.passwordRequired' );
50
         expect( PASSWORD_REQUIRED ).toBe( 'conference.passwordRequired' );
50
         expect( RESERVATION_ERROR ).toBe( 'conference.reservationError' );
51
         expect( RESERVATION_ERROR ).toBe( 'conference.reservationError' );
52
+        expect( REDIRECTED ).toBe( 'conference.redirected' );
51
         expect( VIDEOBRIDGE_NOT_AVAILABLE ).toBe( 'conference.videobridgeNotAvailable' );
53
         expect( VIDEOBRIDGE_NOT_AVAILABLE ).toBe( 'conference.videobridgeNotAvailable' );
52
 
54
 
53
         expect( JitsiConferenceErrors ).toBeDefined();
55
         expect( JitsiConferenceErrors ).toBeDefined();
71
         expect( JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED ).toBe( 'conference.passwordNotSupported' );
73
         expect( JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED ).toBe( 'conference.passwordNotSupported' );
72
         expect( JitsiConferenceErrors.PASSWORD_REQUIRED ).toBe( 'conference.passwordRequired' );
74
         expect( JitsiConferenceErrors.PASSWORD_REQUIRED ).toBe( 'conference.passwordRequired' );
73
         expect( JitsiConferenceErrors.RESERVATION_ERROR ).toBe( 'conference.reservationError' );
75
         expect( JitsiConferenceErrors.RESERVATION_ERROR ).toBe( 'conference.reservationError' );
76
+        expect( JitsiConferenceErrors.REDIRECTED ).toBe( 'conference.redirected' );
74
         expect( JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE ).toBe( 'conference.videobridgeNotAvailable' );
77
         expect( JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE ).toBe( 'conference.videobridgeNotAvailable' );
75
     } );
78
     } );
76
 
79
 
78
         const keys = Object.keys( others );
81
         const keys = Object.keys( others );
79
         expect( keys ).withContext( `Extra members: ${ keys.join( ", " ) }` ).toEqual( [] );
82
         expect( keys ).withContext( `Extra members: ${ keys.join( ", " ) }` ).toEqual( [] );
80
     } );
83
     } );
81
-} );
84
+} );

+ 6
- 0
JitsiConferenceErrors.ts View File

98
      */
98
      */
99
     PASSWORD_REQUIRED = 'conference.passwordRequired',
99
     PASSWORD_REQUIRED = 'conference.passwordRequired',
100
 
100
 
101
+    /**
102
+     * The conference is redirected to a visitor node.
103
+     */
104
+    REDIRECTED = 'conference.redirected',
105
+
101
     /**
106
     /**
102
      * Indicates that reservation system returned error.
107
      * Indicates that reservation system returned error.
103
      */
108
      */
128
 export const OFFER_ANSWER_FAILED = JitsiConferenceErrors.OFFER_ANSWER_FAILED;
133
 export const OFFER_ANSWER_FAILED = JitsiConferenceErrors.OFFER_ANSWER_FAILED;
129
 export const PASSWORD_NOT_SUPPORTED = JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED;
134
 export const PASSWORD_NOT_SUPPORTED = JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED;
130
 export const PASSWORD_REQUIRED = JitsiConferenceErrors.PASSWORD_REQUIRED;
135
 export const PASSWORD_REQUIRED = JitsiConferenceErrors.PASSWORD_REQUIRED;
136
+export const REDIRECTED = JitsiConferenceErrors.REDIRECTED;
131
 export const RESERVATION_ERROR = JitsiConferenceErrors.RESERVATION_ERROR;
137
 export const RESERVATION_ERROR = JitsiConferenceErrors.RESERVATION_ERROR;
132
 export const VIDEOBRIDGE_NOT_AVAILABLE = JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE;
138
 export const VIDEOBRIDGE_NOT_AVAILABLE = JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE;

+ 4
- 0
JitsiConferenceEventManager.js View File

222
         JitsiConferenceEvents.CONFERENCE_FAILED,
222
         JitsiConferenceEvents.CONFERENCE_FAILED,
223
         JitsiConferenceErrors.AUTHENTICATION_REQUIRED);
223
         JitsiConferenceErrors.AUTHENTICATION_REQUIRED);
224
 
224
 
225
+    this.chatRoomForwarder.forward(XMPPEvents.REDIRECTED,
226
+        JitsiConferenceEvents.CONFERENCE_FAILED,
227
+        JitsiConferenceErrors.REDIRECTED);
228
+
225
     this.chatRoomForwarder.forward(XMPPEvents.BRIDGE_DOWN,
229
     this.chatRoomForwarder.forward(XMPPEvents.BRIDGE_DOWN,
226
         JitsiConferenceEvents.CONFERENCE_FAILED,
230
         JitsiConferenceEvents.CONFERENCE_FAILED,
227
         JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);
231
         JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);

+ 7
- 2
modules/xmpp/ChatRoom.js View File

121
         this.myroomjid = jid;
121
         this.myroomjid = jid;
122
         this.password = password;
122
         this.password = password;
123
         this.replaceParticipant = false;
123
         this.replaceParticipant = false;
124
-        logger.info(`Joined MUC as ${this.myroomjid}`);
124
+        logger.info(`Joining MUC as ${this.myroomjid}`);
125
         this.members = {};
125
         this.members = {};
126
         this.presMap = {};
126
         this.presMap = {};
127
         this.presHandlers = {};
127
         this.presHandlers = {};
188
             this.options.disableFocus
188
             this.options.disableFocus
189
                 && logger.info(`Conference focus disabled for ${this.roomjid}`);
189
                 && logger.info(`Conference focus disabled for ${this.roomjid}`);
190
 
190
 
191
+            // there is no point of sending conference iq when in visitor mode
191
             const preJoin
192
             const preJoin
192
-                = this.options.disableFocus
193
+                = this.options.disableFocus || this.options.hosts.visitorFocus
193
                     ? Promise.resolve()
194
                     ? Promise.resolve()
194
                     : this.moderator.allocateConferenceFocus();
195
                     : this.moderator.allocateConferenceFocus();
195
 
196
 
197
+            if (this.options.hosts.visitorFocus) {
198
+                this.moderator.setFocusUserJid(this.options.hosts.visitorFocus);
199
+            }
200
+
196
             preJoin.then(() => {
201
             preJoin.then(() => {
197
                 this.sendPresence(true);
202
                 this.sendPresence(true);
198
                 this._removeConnListeners.push(
203
                 this._removeConnListeners.push(

+ 15
- 0
modules/xmpp/moderator.js View File

375
 
375
 
376
         return;
376
         return;
377
     }
377
     }
378
+
379
+    // redirect
380
+    if ($(error).find('>error>redirect').length) {
381
+        const conferenceIQError = $(error).find('conference');
382
+
383
+        const vnode = conferenceIQError.attr('vnode');
384
+        const focusJid = conferenceIQError.attr('focusjid');
385
+
386
+        logger.warn(`We have been redirected to: ${vnode} new focus Jid:${focusJid}`);
387
+
388
+        this.eventEmitter.emit(XMPPEvents.REDIRECTED, vnode, focusJid);
389
+
390
+        return;
391
+    }
392
+
378
     const waitMs = this.getNextErrorTimeout();
393
     const waitMs = this.getNextErrorTimeout();
379
     const errmsg = `Focus error, retry after ${waitMs}`;
394
     const errmsg = `Focus error, retry after ${waitMs}`;
380
 
395
 

+ 5
- 0
service/xmpp/XMPPEvents.ts View File

204
      */
204
      */
205
     RECORDER_STATE_CHANGED = 'xmpp.recorderStateChanged',
205
     RECORDER_STATE_CHANGED = 'xmpp.recorderStateChanged',
206
 
206
 
207
+    /**
208
+     * The conference was redirected to a visitor node.
209
+     */
210
+    REDIRECTED = 'xmpp.redirected',
211
+
207
     // Designates an event indicating that we received statistics from a
212
     // Designates an event indicating that we received statistics from a
208
     // participant in the MUC.
213
     // participant in the MUC.
209
     REMOTE_STATS = 'xmpp.remote_stats',
214
     REMOTE_STATS = 'xmpp.remote_stats',

Loading…
Cancel
Save