diff --git a/README.md b/README.md
index e32a6384..269dfb6a 100644
--- a/README.md
+++ b/README.md
@@ -248,7 +248,7 @@ sudo systemctl enable edumeet
## Load balanced installation
-To deploy this as a load balanced cluster, have a look at [HAproxy](HAproxy.md).
+To deploy this as a load balanced cluster, have a look at [HAproxy](/docs/HAproxy.md).
## Learning management integration
diff --git a/app/package.json b/app/package.json
index 8cbd2a99..b8e1349f 100644
--- a/app/package.json
+++ b/app/package.json
@@ -43,7 +43,7 @@
"is-electron": "^2.2.0",
"marked": "^0.8.0",
"material-ui-popup-state": "^1.8.0",
- "mediasoup-client": "^3.6.47",
+ "mediasoup-client": "^3.6.55",
"notistack": "^0.9.5",
"prop-types": "^15.7.2",
"random-string": "^0.2.0",
diff --git a/app/public/index.html b/app/public/index.html
index 0060d0fb..966bd069 100644
--- a/app/public/index.html
+++ b/app/public/index.html
@@ -7,6 +7,7 @@
content='width=device-width, initial-scale=1, shrink-to-fit=no'
/>
+
diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js
index dd2f7f87..121f3287 100644
--- a/app/src/RoomClient.js
+++ b/app/src/RoomClient.js
@@ -4283,7 +4283,7 @@ export default class RoomClient
try
{
const device = this._webcams[videoDeviceId];
- const { resolution, aspectRatio } = store.getState().settings;
+ const { resolution, aspectRatio, frameRate } = store.getState().settings;
if (!device)
throw new Error('no webcam devices');
@@ -4293,7 +4293,8 @@ export default class RoomClient
video :
{
deviceId : { ideal: videoDeviceId },
- ...getVideoConstrains(resolution, aspectRatio)
+ ...getVideoConstrains(resolution, aspectRatio),
+ frameRate
}
});
diff --git a/app/src/components/Containers/Peer.js b/app/src/components/Containers/Peer.js
index 3a07d4b9..5546f509 100644
--- a/app/src/components/Containers/Peer.js
+++ b/app/src/components/Containers/Peer.js
@@ -349,21 +349,32 @@ const Peer = (props) =>
{
const handler = setTimeout(() =>
{
- const consumer = webcamConsumer || screenConsumer;
+ const consumers = [];
- if (!consumer)
- return;
+ if (webcamConsumer)
+ consumers.push(webcamConsumer);
- if (windowConsumer === consumer.id)
+ if (screenConsumer)
+ consumers.push(screenConsumer);
+
+ extraVideoConsumers.map((consumer) =>
{
- // if playing in external window, set the maximum quality levels
- roomClient.setConsumerPreferredLayersMax(consumer);
- }
- else if (enableLayersSwitch && consumer?.type !== 'simple'
- && fullScreenConsumer !== consumer.id)
+ consumers.push(consumer);
+ });
+
+ consumers.forEach((consumer) =>
{
- roomClient.adaptConsumerPreferredLayers(consumer, width, height);
- }
+ if (windowConsumer === consumer.id)
+ {
+ // if playing in external window, set the maximum quality levels
+ roomClient.setConsumerPreferredLayersMax(consumer);
+ }
+ else if (enableLayersSwitch && consumer?.type !== 'simple'
+ && fullScreenConsumer !== consumer.id)
+ {
+ roomClient.adaptConsumerPreferredLayers(consumer, width, height);
+ }
+ });
}, 1000);
return () => { clearTimeout(handler); };
@@ -371,6 +382,7 @@ const Peer = (props) =>
enableLayersSwitch,
webcamConsumer,
screenConsumer,
+ extraVideoConsumers,
windowConsumer,
fullScreenConsumer,
roomClient, width, height
diff --git a/app/src/components/VideoContainers/VideoView.js b/app/src/components/VideoContainers/VideoView.js
index 261ca0e7..7d7f3969 100644
--- a/app/src/components/VideoContainers/VideoView.js
+++ b/app/src/components/VideoContainers/VideoView.js
@@ -437,6 +437,7 @@ class VideoView extends React.PureComponent
localRecordingState==='resume'
)&&
(
+ recordingConsents!==undefined &&
!recordingConsents.includes(peer.id)
)
) ? '':displayName
@@ -459,6 +460,7 @@ class VideoView extends React.PureComponent
localRecordingState==='resume'
)&&
(
+ recordingConsents!==undefined &&
!recordingConsents.includes(peer.id)
)
)
diff --git a/compose/edumeet/Dockerfile b/compose/edumeet/Dockerfile
index 2e801cb6..58ebd82b 100644
--- a/compose/edumeet/Dockerfile
+++ b/compose/edumeet/Dockerfile
@@ -1,6 +1,6 @@
FROM node:14-buster-slim
RUN apt-get update && \
- apt-get install -y git build-essential python pkg-config libssl-dev && \
+ apt-get install -y git build-essential python pkg-config libssl-dev python3-pip && \
apt-get clean
WORKDIR /edumeet
ENV DEBUG=edumeet*,mediasoup*
diff --git a/docs/HAproxy.md b/docs/HAproxy.md
index 2166f393..14dc05b9 100644
--- a/docs/HAproxy.md
+++ b/docs/HAproxy.md
@@ -64,13 +64,17 @@ OR
### Server config
-mm/configs/server/config.js
-
-``` js
-redisOptions : { host: '192.0.2.4'},
-listeningPort: 80,
-httpOnly: true,
-trustProxy : ['192.0.2.5'],
+config.yaml
+``` yaml
+turnAPIKey : ""
+turnAPIURI : ""
+listeningPort : 80
+httpOnly : true
+trustProxy : "192.0.2.5"
+redisOptions:
+ host: "192.0.2.4"
+ port: "6379"
+ password: "passwd"
```
## Deploy HA proxy
@@ -78,24 +82,121 @@ trustProxy : ['192.0.2.5'],
* Configure certificate / letsencrypt for `meet.example.com`
* In this example we put a complete chain and private key in /root/certificate.pem.
* Install and setup haproxy
+```bash
+apt install haproxy
+```
+* Install haproxy 2.2 (recommended)
+``` bash
+sudo apt-get install gnupg2 curl -y
+curl https://haproxy.debian.net/bernat.debian.org.gpg | sudo apt-key add -
+echo deb http://haproxy.debian.net buster-backports-2.2 main | sudo tee /etc/apt/sources.list.d/haproxy.list
+sudo apt-get update
+apt-get install haproxy=2.2.\*
- `apt install haproxy`
+sudo systemctl start haproxy
+sudo systemctl enable haproxy
+```
* Add to /etc/haproxy/haproxy.cfg config
``` plaintext
- backend edumeet
- balance url_param roomId
- hash-type consistent
- server mm1 192.0.2.1:80 check maxconn 2000 verify none
- server mm2 192.0.2.2:80 check maxconn 2000 verify none
- server mm3 192.0.2.3:80 check maxconn 2000 verify none
+ global
+ # mult thread setup
+ nbproc 1
+ nbthread 4
+ cpu-map auto:1/1-4 0-3
+
+ log /dev/log local0
+ log /dev/log local1 notice
+ chroot /var/lib/haproxy
+ stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
+ stats socket /run/haproxy.sock mode 660 level admin
+ stats timeout 30s
+ user haproxy
+ group haproxy
+ daemon
+
+ # Default SSL material locations
+ ca-base /etc/ssl/certs
+ crt-base /etc/ssl/private
+
+ # Default ciphers to use on SSL-enabled listening sockets.
+ # For more information, see ciphers(1SSL). This list is from:
+ # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
+ # An alternative list with additional directives can be obtained from
+ # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
+ ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
+ ssl-default-bind-options no-sslv3
+ tune.ssl.default-dh-param 2048
+ maxconn 20000
+
+ defaults
+ log global
+ mode http
+ option httplog
+ #option logasap
+ #option dontlognull
+ timeout connect 5000
+ timeout client 50000
+ timeout server 50000
+ errorfile 400 /etc/haproxy/errors/400.http
+ errorfile 403 /etc/haproxy/errors/403.http
+ errorfile 408 /etc/haproxy/errors/408.http
+ errorfile 500 /etc/haproxy/errors/500.http
+ errorfile 502 /etc/haproxy/errors/502.http
+ errorfile 503 /etc/haproxy/errors/503.http
+ errorfile 504 /etc/haproxy/errors/504.http
+ maxconn 8192
+
+ backend letsmeet-room-backend
+ fullconn 4000
+ balance url_param roomId
+ hash-type consistent
+ stick-table type string len 1024 size 100k expire 8h
+ stick store-request url_param(roomId)
+ stick match url_param(roomId)
+ stick match url_param(state),url_dec,b64dec,field(8,'\"')
+
+ server edumeet1 192.0.2.1:80 check maxconn 2000 verify none
+ server edumeet2 192.0.2.2:80 check maxconn 1000 verify none
+ server edumeet3 192.0.2.3:80 check maxconn 1000 verify none
+
+ backend letsmeet-backend
+ fullconn 4000
+ balance leastconn
+ stick-table type ip size 200k expire 30m
+ stick on src
+ hash-type consistent
+
+ server edumeet1 192.0.2.1:80 check maxconn 2000 verify none
+ server edumeet2 192.0.2.2:80 check maxconn 1000 verify none
+ server edumeet3 192.0.2.3:80 check maxconn 1000 verify none
+
+ frontend letsmeet
+ bind *:80
+ bind*:443 ssl crt /etc/ssl/edumeet.example.com/edumeet.example.com.pem alpn h2,http/1.1
+ http-request redirect scheme https if !{ ssl_fc }
+ http-request add-header X-Forwarded-Proto https
+ stats enable
+ stats uri /static/stats
+ #stats hide-version
+ stats refresh 10s
+ stats admin if TRUE
+ #stats admin if LOCALHOST
+ stats realm Haproxy\ Statistics
+ stats auth admin:password
+
+ maxconn 6000
+ acl roomId-acl url_param(roomId) -m found
+ acl callback-acl path_beg /auth/callback
+ use_backend letsmeet-room-backend if roomId-acl || callback-acl
+ default_backend letsmeet-backend
- frontend meet.example.com
- bind 192.0.2.5:80
- bind 192.0.2.5:443 ssl crt /root/certificate.pem
- http-request redirect scheme https unless { ssl_fc }
- reqadd X-Forwarded-Proto:\ https
- default_backend edumeet
```
+
+* Creating cert with letsencrypt :
+
+``` bash
+sudo cat /etc/letsencrypt/live/edumeet.example.com/fullchain.pem /etc/letsencrypt/live/edumeet.example.com/privkey.pem | sudo tee /etc/ssl/edumeet.example.com/edumeet.example.com.pem
+```
diff --git a/server/package.json b/server/package.json
index f0e47525..39fcc301 100644
--- a/server/package.json
+++ b/server/package.json
@@ -43,7 +43,7 @@
"ims-lti": "^3.0.2",
"json5": "^2.2.0",
"jsonwebtoken": "^8.5.1",
- "mediasoup": "3.9.6",
+ "mediasoup": "3.10.5",
"openid-client": "^3.7.3",
"passport": "^0.4.0",
"passport-local": "^1.0.0",