From f5668b6e8be2e79f6f6a968ab6c53d0e03e2c950 Mon Sep 17 00:00:00 2001 From: damencho Date: Thu, 18 Sep 2025 11:19:49 -0500 Subject: [PATCH] feat(visitors): Retries as a visitor when max occupants reached. --- .../base/conference/middleware.any.ts | 40 ++++++++++++++++--- .../prosody-plugins/mod_muc_max_occupants.lua | 4 +- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/react/features/base/conference/middleware.any.ts b/react/features/base/conference/middleware.any.ts index ca58e329ea..ea9cd91aef 100644 --- a/react/features/base/conference/middleware.any.ts +++ b/react/features/base/conference/middleware.any.ts @@ -26,7 +26,7 @@ import { AudioMixerEffect } from '../../stream-effects/audio-mixer/AudioMixerEff import { iAmVisitor } from '../../visitors/functions'; import { overwriteConfig } from '../config/actions'; import { CONNECTION_ESTABLISHED, CONNECTION_FAILED, CONNECTION_WILL_CONNECT } from '../connection/actionTypes'; -import { connectionDisconnected, disconnect } from '../connection/actions'; +import { connect, connectionDisconnected, disconnect, setPreferVisitor } from '../connection/actions'; import { validateJwt } from '../jwt/functions'; import { JitsiConferenceErrors, JitsiConferenceEvents, JitsiConnectionErrors } from '../lib-jitsi-meet'; import { MEDIA_TYPE } from '../media/constants'; @@ -78,6 +78,11 @@ import { IConferenceMetadata } from './reducer'; */ let beforeUnloadHandler: ((e?: any) => void) | undefined; +/** + * A simple flag to avoid retrying more than once to join as a visitor when hitting max occupants reached. + */ +let retryAsVisitorOnMaxError = true; + /** * Implements the middleware of the feature base/conference. * @@ -202,11 +207,20 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio break; } case JitsiConferenceErrors.CONFERENCE_MAX_USERS: { - dispatch(showErrorNotification({ - hideErrorSupportLink: true, - descriptionKey: 'dialog.maxUsersLimitReached', - titleKey: 'dialog.maxUsersLimitReachedTitle' - })); + let retryAsVisitor = false; + + if (error.params?.length && error.params[0]?.visitorsSupported) { + // visitors are supported, so let's try joining that way + retryAsVisitor = true; + } + + if (!retryAsVisitor) { + dispatch(showErrorNotification({ + hideErrorSupportLink: true, + descriptionKey: 'dialog.maxUsersLimitReached', + titleKey: 'dialog.maxUsersLimitReachedTitle' + })); + } // In case of max users(it can be from a visitor node), let's restore // oldConfig if any as we will be back to the main prosody. @@ -220,6 +234,18 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio .then(() => dispatch(disconnect())); } + if (retryAsVisitor && !newConfig && retryAsVisitorOnMaxError) { + retryAsVisitorOnMaxError = false; + + logger.info('On max user reached will retry joining as a visitor'); + + dispatch(disconnect(true)).then(() => { + dispatch(setPreferVisitor(true)); + + return dispatch(connect()); + }); + } + break; } case JitsiConferenceErrors.NOT_ALLOWED_ERROR: { @@ -300,6 +326,8 @@ function _conferenceJoined({ dispatch, getState }: IStore, next: Function, actio requireDisplayName } = getState()['features/base/config']; + retryAsVisitorOnMaxError = true; + dispatch(removeLobbyChatParticipant(true)); pendingSubjectChange && dispatch(setSubject(pendingSubjectChange)); diff --git a/resources/prosody-plugins/mod_muc_max_occupants.lua b/resources/prosody-plugins/mod_muc_max_occupants.lua index 63a089736f..4a4892c93e 100644 --- a/resources/prosody-plugins/mod_muc_max_occupants.lua +++ b/resources/prosody-plugins/mod_muc_max_occupants.lua @@ -43,7 +43,7 @@ local function check_for_max_occupants(event) -- If there is no whitelist, just check the count. if not whitelist and count >= slots then - module:log("info", "Attempt to enter a maxed out MUC"); + module:log("info", "Attempt to enter a maxed out room: %s", room.jid); origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return true; end @@ -60,7 +60,7 @@ local function check_for_max_occupants(event) -- If the room is full (<0 slots left), error out. if slots <= 0 then - module:log("info", "Attempt to enter a maxed out MUC"); + module:log("info", "Attempt to enter a maxed out room:%s", room.jid); origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return true; end