edumeet: Bug: unable to join more then 19 peers in a room
Hi,
we have a problem that we are unable to join more then 19 persons in a meeting. When extra people try to join while not authenticated (they access lobby), I get list of blank users (pic in attachment). If more than 19 moderators try to access same room, they end up in an empty room on the same URL. Here is our entire server config:
const os = require('os');
const userRoles = require('../userRoles');
const {
BYPASS_ROOM_LOCK,
BYPASS_LOBBY
} = require('../access');
const {
CHANGE_ROOM_LOCK,
PROMOTE_PEER,
MODIFY_ROLE,
SEND_CHAT,
MODERATE_CHAT,
SHARE_AUDIO,
SHARE_VIDEO,
SHARE_SCREEN,
EXTRA_VIDEO,
SHARE_FILE,
MODERATE_FILES,
MODERATE_ROOM
} = require('../permissions');
const AwaitQueue = require('awaitqueue');
// const axios = require('axios');
module.exports =
{
// Auth conf
auth :
{
lti :
{
consumerKey : 'xxxx',
consumerSecret : 'xxxxx'
},
strategy : 'oidc',
oidc:
{
// The issuer URL for OpenID Connect discovery
// The OpenID Provider Configuration Document
// could be discovered on:
// issuerURL + '/.well-known/openid-configuration'
issuerURL : 'xxxxxxx,
clientOptions :
{
client_id : 'xxxxxxx',
client_secret : 'xxxxxxx',
scope : 'openid profile email cn hrEduPersonAffiliation',
// where client.example.com is your multiparty meeting server
redirect_uri : 'xxxxxxx'
}
}
},
// URI and key for requesting geoip-based TURN server closest to the client
turnAPIKey : 'xxxxxxx',
turnAPIURI : 'https://api.turn.geant.org/turn',
turnAPIparams : {
'uri_schema' : 'turn',
'transport' : 'tcp',
'ip_ver' : 'ipv4',
'servercount' : '2'
},
// Backup turnservers if REST fails or is not configured
backupTurnServers : [
{
urls : [
'turn:ltc.turn.geant.org:443?transport=tcp'
],
username : 'xxxxxxx',
credential : 'xxxxxxx'
}
],
fileTracker : 'wss://tracker.lab.vvc.niif.hu:443',
//redisOptions : {},
//redisOptions : { host: '10.8.62.11' },
redisOptions : { host: 'xxxxxxx', prefix: 'meet_'},
// session cookie secret
cookieSecret : 'T0P-S3cR3t_cook!e',
cookieName : 'edumeet.sid',
// if you use encrypted private key the set the passphrase
tls :
{
cert : `${__dirname}/../certs/mediasoup-demo.localhost.cert.pem`,
// passphrase: 'key_password'
key : `${__dirname}/../certs/mediasoup-demo.localhost.key.pem`
},
// listening Host or IP
// If omitted listens on every IP. ("0.0.0.0" and "::")
// listeningHost: 'localhost',
// Listening port for https server.
listeningPort : 80,
// Any http request is redirected to https.
// Listening port for http server.
//listeningRedirectPort : 80,
// Listens only on http, only on listeningPort
// listeningRedirectPort disabled
// use case: loadbalancer backend
httpOnly : true,
// WebServer/Express trust proxy config for httpOnly mode
// You can find more info:
// - https://expressjs.com/en/guide/behind-proxies.html
// - https://www.npmjs.com/package/proxy-addr
// use case: loadbalancer backend
trustProxy : '161.53.2.121, 161.53.2.122',
//trustProxy : '161.53.252.203',
// This logger class will have the log function
// called every time there is a room created or destroyed,
// or peer created or destroyed. This would then be able
// to log to a file or external service.
StatusLogger : class
{
constructor()
{
this._queue = new AwaitQueue();
}
// rooms: rooms object
// peers: peers object
// eslint-disable-next-line no-unused-vars
async log({ rooms, peers })
{
this._queue.push(async () =>
{
// Do your logging in here, use queue to keep correct order
// eslint-disable-next-line no-console
// eslint-disable-next-line no-console
})
.catch((error) =>
{
// eslint-disable-next-line no-console
console.log('error in log', error);
});
}
},
// This function will be called on successful login through oidc.
// Use this function to map your oidc userinfo to the Peer object.
// The roomId is equal to the room name.
userMapping : async ({ peer, roomId, userinfo }) =>
{
if (userinfo.picture != null)
{
if (!userinfo.picture.match(/^http/g))
{
peer.picture = `data:image/jpeg;base64, ${userinfo.picture}`;
}
else
{
peer.picture = userinfo.picture;
}
}
if (userinfo.nickname != null)
{
peer.displayName = userinfo.nickname;
}
if (userinfo.name != null)
{
peer.displayName = userinfo.name;
}
if (userinfo.email != null)
{
peer.email = userinfo.email;
}
if (userinfo.lti && userinfo.lti.roles && userinfo.lti.roles.includes('Administrator'))
{
peer.addRole(userRoles.AUTHENTICATED);
peer.addRole(userRoles.ADMIN);
}
if (userinfo.lti && userinfo.lti.roles && userinfo.lti.roles.includes('Instructor'))
{
peer.addRole(userRoles.AUTHENTICATED);
peer.addRole(userRoles.MODERATOR);
}
if (userinfo.lti && userinfo.lti.roles && userinfo.lti.roles.includes('Learner'))
{
peer.addRole(userRoles.AUTHENTICATED);
}
if (userinfo.hrEduPersonAffiliation)
{
peer.displayName = userinfo.cn[0];
peer.addRole(userRoles.AUTHENTICATED);
if (userinfo.hrEduPersonAffiliation.includes('djelatnik') && userinfo.email.endsWith('@srce.hr'))
{
peer.addRole(userRoles.MODERATOR);
}
}
},
// All users have the role "NORMAL" by default. Other roles need to be
// added in the "userMapping" function. The following accesses and
// permissions are arrays of roles. Roles can be changed in userRoles.js
//
// Example:
// [ userRoles.MODERATOR, userRoles.AUTHENTICATED ]
accessFromRoles : {
// The role(s) will gain access to the room
// even if it is locked (!)
[BYPASS_ROOM_LOCK] : [ userRoles.MODERATOR ],
// The role(s) will gain access to the room without
// going into the lobby. If you want to restrict access to your
// server to only directly allow authenticated users, you could
// add the userRoles.AUTHENTICATED to the user in the userMapping
// function, and change to BYPASS_LOBBY : [ userRoles.AUTHENTICATED ]
[BYPASS_LOBBY] : [ userRoles.AUTHENTICATED ]
},
permissionsFromRoles : {
// The role(s) have permission to lock/unlock a room
[CHANGE_ROOM_LOCK] : [ userRoles.MODERATOR ],
// The role(s) have permission to promote a peer from the lobby
[PROMOTE_PEER] : [ userRoles.MODERATOR ],
// The role(s) have permission to give/remove other peers roles
[MODIFY_ROLE] : [ userRoles.MODERATOR ],
// The role(s) have permission to send chat messages
[SEND_CHAT] : [ userRoles.NORMAL ],
// The role(s) have permission to moderate chat
[MODERATE_CHAT] : [ userRoles.MODERATOR ],
// The role(s) have permission to share audio
[SHARE_AUDIO] : [ userRoles.MODERATOR, userRoles.PRESENTER ],
// The role(s) have permission to share video
[SHARE_VIDEO] : [ userRoles.MODERATOR, userRoles.PRESENTER ],
// The role(s) have permission to share screen
[SHARE_SCREEN] : [ userRoles.MODERATOR, userRoles.PRESENTER ],
// The role(s) have permission to produce extra video
[EXTRA_VIDEO] : [ userRoles.MODERATOR, userRoles.PRESENTER ],
// The role(s) have permission to share files
[SHARE_FILE] : [ userRoles.MODERATOR, userRoles.PRESENTER ],
// The role(s) have permission to moderate files
[MODERATE_FILES] : [ userRoles.MODERATOR ],
// The role(s) have permission to moderate room (e.g. kick user)
[MODERATE_ROOM] : [ userRoles.MODERATOR ]
},
// Array of permissions. If no peer with the permission in question
// is in the room, all peers are permitted to do the action. The peers
// that are allowed because of this rule will not be able to do this
// action as soon as a peer with the permission joins. In this example
// everyone will be able to lock/unlock room until a MODERATOR joins.
//allowWhenRoleMissing : [ CHANGE_ROOM_LOCK ],
// When truthy, the room will be open to all users when as long as there
// are allready users in the room
activateOnHostJoin : false,
// When set, maxUsersPerRoom defines how many users can join
// a single room. If not set, there is no limit.
// maxUsersPerRoom : 20,
// Room size before spreading to new router
routerScaleSize : 40,
// Socket timout value
requestTimeout : 20000,
// Socket retries when timeout
requestRetries : 3,
// Mediasoup settings
mediasoup :
{
numWorkers : Object.keys(os.cpus()).length,
// mediasoup Worker settings.
worker :
{
logLevel : 'warn',
logTags :
[
'info',
'ice',
'dtls',
'rtp',
'srtp',
'rtcp'
],
rtcMinPort : 40000,
rtcMaxPort : 49999
},
// mediasoup Router settings.
router :
{
// Router media codecs.
mediaCodecs :
[
{
kind : 'audio',
mimeType : 'audio/opus',
clockRate : 48000,
channels : 2
},
{
kind : 'video',
mimeType : 'video/VP8',
clockRate : 90000,
parameters :
{
'x-google-start-bitrate' : 1000
}
},
{
kind : 'video',
mimeType : 'video/VP9',
clockRate : 90000,
parameters :
{
'profile-id' : 2,
'x-google-start-bitrate' : 1000
}
},
{
kind : 'video',
mimeType : 'video/h264',
clockRate : 90000,
parameters :
{
'packetization-mode' : 1,
'profile-level-id' : '4d0032',
'level-asymmetry-allowed' : 1,
'x-google-start-bitrate' : 1000
}
},
{
kind : 'video',
mimeType : 'video/h264',
clockRate : 90000,
parameters :
{
'packetization-mode' : 1,
'profile-level-id' : '42e01f',
'level-asymmetry-allowed' : 1,
'x-google-start-bitrate' : 1000
}
}
]
},
// mediasoup WebRtcTransport settings.
webRtcTransport :
{
listenIps :
[
// change 192.0.2.1 IPv4 to your server's IPv4 address!!
{ ip: '161.53.3.177', announcedIp: null }
// Can have multiple listening interfaces
// change 2001:DB8::1 IPv6 to your server's IPv6 address!!
// { ip: '2001:DB8::1', announcedIp: null }
],
initialAvailableOutgoingBitrate : 1000000,
minimumAvailableOutgoingBitrate : 600000,
// Additional options that are not part of WebRtcTransportOptions.
maxIncomingBitrate : 1500000
}
}
// Prometheus exporter
/*
prometheus: {
deidentify: false, // deidentify IP addresses
numeric: false, // show numeric IP addresses
port: 8889, // allocated port
quiet: false // include fewer labels
}
*/
};
We have 3 servers in a cluster, and are using develop branch some 2 weeks old (with b7f07dcce9466204a901122dc881bc58af28b250 revision).
Has anyone experienced this kind of problem and how to fix it?
Best, Zvonko
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 25
Hell, just looked at HAProxy config and yes, we did have 20 connections limit -_- (probably copy&paste from https://github.com/edumeet/edumeet/blob/master/HAproxy.md and forgot to update)
server meet01.srce.hr XXX.XXX.XXX.XXX:80 check maxconn 20 verify noneEven on our Moodle servers we have 300 connections, so it was a mistake on our part. Tomorrow we will test with a new maxconn settings and will let you know. Thanks @Astagor and @so010 for your help 😃