mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 11:22:31 +00:00
fix(visitors): Fixes going live when the meeting is created. (#14905)
* fix(visitors): Fixes going live when first moderator joins. * squash(jwt): Drop unused field. * squash(jwt): Fixes loading token_util for visitors component. * squash(jwt): Validate nbf if it exists as it is optional. * squash(visitors): Keep prefer visitor state for not live meetings. * squash(visitors): Automatically go live only when there is a moderator in the meeting. * squash(visitors): Automatically go live only when there is an occupant in the meeting. * squash(visitors): Drops a debug log. * squash(visitors): Makes sure we first disconnect before attempting a reconnect. If the reconnect happens too quickly, before being disconnected and the conference is still not live we will detect that we are still connected and will skip connecting to visitors service, and in the next moment we will disconnect. * squash(visitors): Slow down successful reconnects. If a meeting was just live but was destroyed jicofo will return it is not live, but service will return that it just got live. Slows down reconnects and at some point the service will return that the meeting is not live. The drawback is that it will take some time to connect when the meeting is created and back live. * squash(visitors): Randomize the delay up to the available value.
This commit is contained in:
@@ -147,6 +147,13 @@ function _connectionFailed(
|
||||
return state;
|
||||
}
|
||||
|
||||
let preferVisitor;
|
||||
|
||||
if (error.name === JitsiConnectionErrors.NOT_LIVE_ERROR) {
|
||||
// we want to keep the state for the moment when the meeting is live
|
||||
preferVisitor = state.preferVisitor;
|
||||
}
|
||||
|
||||
return assign(state, {
|
||||
connecting: undefined,
|
||||
connection: undefined,
|
||||
@@ -154,7 +161,7 @@ function _connectionFailed(
|
||||
passwordRequired:
|
||||
error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
|
||||
? connection : undefined,
|
||||
preferVisitor: undefined
|
||||
preferVisitor
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -176,10 +176,12 @@ export function validateJwt(jwt: string) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValidUnixTimestamp(nbf)) {
|
||||
errors.push({ key: JWT_VALIDATION_ERRORS.NBF_INVALID });
|
||||
} else if (currentTimestamp < nbf * 1000) {
|
||||
errors.push({ key: JWT_VALIDATION_ERRORS.NBF_FUTURE });
|
||||
if (nbf) { // nbf value is optional
|
||||
if (!isValidUnixTimestamp(nbf)) {
|
||||
errors.push({ key: JWT_VALIDATION_ERRORS.NBF_INVALID });
|
||||
} else if (currentTimestamp < nbf * 1000) {
|
||||
errors.push({ key: JWT_VALIDATION_ERRORS.NBF_FUTURE });
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValidUnixTimestamp(exp)) {
|
||||
|
||||
@@ -178,19 +178,25 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
if ('status' in msg && msg.status === 'live') {
|
||||
logger.info('The conference is now live!');
|
||||
|
||||
WebsocketClient.getInstance().disconnect();
|
||||
WebsocketClient.getInstance().disconnect()
|
||||
.then(() => {
|
||||
let delay = 0;
|
||||
|
||||
let delay = 0;
|
||||
// now let's connect to meeting
|
||||
if ('randomDelayMs' in msg) {
|
||||
delay = msg.randomDelayMs;
|
||||
}
|
||||
|
||||
// now let's connect to meeting
|
||||
if ('randomDelayMs' in msg) {
|
||||
delay = msg.randomDelayMs;
|
||||
}
|
||||
if (WebsocketClient.getInstance().connectCount > 1) {
|
||||
// if we keep connecting/disconnecting, let's slow it down
|
||||
delay = 30 * 1000;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
dispatch(joinConference());
|
||||
dispatch(setInVisitorsQueue(false));
|
||||
}, delay);
|
||||
setTimeout(() => {
|
||||
dispatch(joinConference());
|
||||
dispatch(setInVisitorsQueue(false));
|
||||
}, Math.random() * delay);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ export class WebsocketClient {
|
||||
|
||||
private retriesCount = 0;
|
||||
|
||||
private _connectCount = 0;
|
||||
|
||||
/**
|
||||
* WebsocketClient getInstance.
|
||||
*
|
||||
@@ -95,6 +97,7 @@ export class WebsocketClient {
|
||||
this.retriesCount = 0;
|
||||
|
||||
logger.info(`Connected to:${endpoint}`);
|
||||
this._connectCount++;
|
||||
connectCallback?.();
|
||||
|
||||
this.stompClient.subscribe(endpoint, message => {
|
||||
@@ -112,16 +115,16 @@ export class WebsocketClient {
|
||||
/**
|
||||
* Disconnects the current stomp client instance and clears it.
|
||||
*
|
||||
* @returns {void}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
disconnect(): void {
|
||||
disconnect(): Promise<any> {
|
||||
if (!this.stompClient) {
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const url = this.stompClient.brokerURL;
|
||||
|
||||
this.stompClient.deactivate().then(() => {
|
||||
return this.stompClient.deactivate().then(() => {
|
||||
logger.info(`disconnected from: ${url}`);
|
||||
this.stompClient = undefined;
|
||||
});
|
||||
@@ -135,4 +138,13 @@ export class WebsocketClient {
|
||||
isActive() {
|
||||
return this.stompClient !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of connections.
|
||||
*
|
||||
* @returns {number} The number of connections for the life of the app.
|
||||
*/
|
||||
get connectCount(): number {
|
||||
return this._connectCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ local um_is_admin = require 'core.usermanager'.is_admin;
|
||||
local json = require 'cjson.safe';
|
||||
local inspect = require 'inspect';
|
||||
|
||||
local token_util = module:require 'token/util'.new(module);
|
||||
-- will be initialized once the main virtual host module is initialized
|
||||
local token_util;
|
||||
|
||||
local MUC_NS = 'http://jabber.org/protocol/muc';
|
||||
|
||||
@@ -304,14 +305,34 @@ local function process_promotion_response(room, id, approved)
|
||||
allow = approved }):up());
|
||||
end
|
||||
|
||||
-- if room metadata does not have visitors.live set to `true` and there are no occupants in the meeting
|
||||
-- it will skip calling goLive endpoint
|
||||
local function go_live(room)
|
||||
if room._jitsi_go_live_sent then
|
||||
return;
|
||||
end
|
||||
|
||||
if not (room.jitsiMetadata and room.jitsiMetadata.visitors and room.jitsiMetadata.visitors.live) then
|
||||
return;
|
||||
end
|
||||
|
||||
local has_occupant = false;
|
||||
for _, occupant in room:each_occupant() do
|
||||
if not is_admin(occupant.bare_jid) then
|
||||
has_occupant = true;
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
-- when there is an occupant then go live
|
||||
if not has_occupant then
|
||||
return;
|
||||
end
|
||||
|
||||
-- let's inform the queue service
|
||||
local function cb(content_, code_, response_, request_)
|
||||
local room = room;
|
||||
if code_ == 200 then
|
||||
-- meeting went live ???
|
||||
module:log('info', 'live')
|
||||
else
|
||||
if code_ ~= 200 then
|
||||
module:log('warn', 'External call to visitors_queue_service/golive failed. Code %s, Content %s',
|
||||
code_, content_)
|
||||
end
|
||||
@@ -324,6 +345,8 @@ local function go_live(room)
|
||||
conference = internal_room_jid_match_rewrite(room.jid)
|
||||
};
|
||||
|
||||
room._jitsi_go_live_sent = true;
|
||||
|
||||
http.request(visitors_queue_service..'/golive', {
|
||||
headers = headers,
|
||||
method = 'POST',
|
||||
@@ -333,6 +356,10 @@ end
|
||||
|
||||
module:hook('iq/host', stanza_handler, 10);
|
||||
|
||||
process_host_module(muc_domain_base, function(host_module, host)
|
||||
token_util = module:require "token/util".new(host_module);
|
||||
end);
|
||||
|
||||
process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_module, host)
|
||||
-- if visitor mode is started, then you are not allowed to join without request/response exchange of iqs -> deny access
|
||||
-- check list of allowed jids for the room
|
||||
@@ -496,18 +523,20 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
|
||||
return;
|
||||
end
|
||||
|
||||
if room.jitsiMetadata and room.jitsiMetadata.visitors and room.jitsiMetadata.visitors.live then
|
||||
go_live(room);
|
||||
end
|
||||
go_live(room);
|
||||
end, -2); -- metadata hook on -1
|
||||
host_module:hook('jitsi-metadata-updated', function (event)
|
||||
if event.key == 'visitors' then
|
||||
local room = event.room;
|
||||
if room.jitsiMetadata and room.jitsiMetadata.visitors and room.jitsiMetadata.visitors.live then
|
||||
go_live(room);
|
||||
end
|
||||
go_live(event.room);
|
||||
end
|
||||
end);
|
||||
-- when metadata changed internally from another module
|
||||
host_module:hook('room-metadata-changed', function (event)
|
||||
go_live(event.room);
|
||||
end);
|
||||
host_module:hook('muc-occupant-joined', function (event)
|
||||
go_live(event.room);
|
||||
end);
|
||||
end
|
||||
|
||||
if always_visitors_enabled then
|
||||
|
||||
@@ -247,13 +247,8 @@ end
|
||||
-- session.jitsi_meet_context_group - the group value from the token
|
||||
-- session.jitsi_meet_context_features - the features value from the token
|
||||
-- @param session the current session
|
||||
-- @param acceptedIssuers optional list of accepted issuers to check
|
||||
-- @return false and error
|
||||
function Util:process_and_verify_token(session, acceptedIssuers)
|
||||
if not acceptedIssuers then
|
||||
acceptedIssuers = self.acceptedIssuers;
|
||||
end
|
||||
|
||||
function Util:process_and_verify_token(session)
|
||||
if session.auth_token == nil then
|
||||
if self.allowEmptyToken then
|
||||
return true;
|
||||
@@ -310,7 +305,7 @@ function Util:process_and_verify_token(session, acceptedIssuers)
|
||||
session.auth_token,
|
||||
self.signatureAlgorithm,
|
||||
key,
|
||||
acceptedIssuers,
|
||||
self.acceptedIssuers,
|
||||
self.acceptedAudiences
|
||||
)
|
||||
if claims ~= nil then
|
||||
|
||||
Reference in New Issue
Block a user