bigbluebutton-Github/bigbluebutton-html5/imports/utils/fetchStunTurnServers.js
Daniel Schreiber c46556e1f6 Allow BBB to run behind a proxy the avoid gUM permission queries per node
The idea is to run a loadbalancer node which maps each BBB node to a
path. That way each user gets only one gUM permission query for a
cluster. The loadbalancer node only serves the html5 client, each BBB
node will serve its own API and handle the websockets for freeswitch and
bbb-webrtc-sfu.

Configuring a cluster setup
===========================

* let bbb-lb.example.com be the loadbalancer node
* let bbb-01.eaxmple.com be a BBB node

Loadbalancer
------------

On the loadbalancer node add an nginx configuration similar to this one
for each BBB node:

```
location /bbb-01/html5client/ {
  proxy_pass https://bbb-01.example.com/bbb-01/html5client/;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
}

```

BBB Node
--------

On the BBB node add the following options to
`/etc/bigbluebutton/bbb-web.properties`:

```
defaultHTML5ClientUrl=https://bbb-lb.example.com/bbb-01/html5client/join
presentationBaseURL=https://bbb-01.example.com/bigbluebutton/presentation
accessControlAllowOrigin=https://bbb-lb.example.com
```

Add the following options to `/etc/bigbluebutton/bbb-html5.yml`:

```
public:
  app:
    basename: '/bbb-01/html5client'
    bbbWebBase: 'https://bbb-01.eaxmple.com/bigbluebutton'
    learningDashboardBase: 'https://bbb-01.eaxmple.com/learning-dashboard'
  media:
    stunTurnServersFetchAddress: 'https://bbb-01.eaxmple.com/bigbluebutton/api/stuns'
    sip_ws_host: 'bbb-01.eaxmple.com'
  presentation:
    uploadEndpoint: 'https://bbb-01.eaxmple.com/bigbluebutton/presentation/upload'
```

Create the following unit file overrides:

* `/etc/systemd/system/bbb-html5-frontend@.service.d/cluster.conf`
* `/etc/systemd/system/bbb-html5-backend@.service.d/cluster.conf`

with the following content:

```
[Service]
Environment=ROOT_URL=https://127.0.0.1/bbb-01/html5client
```

Change the nginx `$bbb_loadbalancer_node` variable to the name of the
load balancer node in `/etc/bigbluebutton/nginx/loadbalancer.nginx` to
allow CORS requests:

```
set $bbb_loadbalancer_node https://bbb-lb.example.com
```

Prepend the mount point of bbb-html5 in all location sections except
from the `location @html5client` section in
`/etc/bigbluebutton/nginx/bbb-html5.nginx`

```
location @html5client {
    ...
}
location /bbb-01/html5client/locales {
    ...
}
```
2021-11-20 22:13:47 +01:00

81 lines
2.2 KiB
JavaScript

import _ from 'lodash';
const MEDIA = Meteor.settings.public.media;
const STUN_TURN_FETCH_URL = MEDIA.stunTurnServersFetchAddress;
const CACHE_STUN_TURN = MEDIA.cacheStunTurnServers;
const FALLBACK_STUN_SERVER = MEDIA.fallbackStunServer;
let STUN_TURN_DICT;
let MAPPED_STUN_TURN_DICT;
const fetchStunTurnServers = function (sessionToken) {
if (STUN_TURN_DICT && CACHE_STUN_TURN) return Promise.resolve(STUN_TURN_DICT);
const handleStunTurnResponse = ({ stunServers, turnServers }) => {
if (!stunServers && !turnServers) {
return Promise.reject(new Error('Could not fetch STUN/TURN servers'));
}
const turnReply = [];
_.each(turnServers, (turnEntry) => {
const { password, url, username } = turnEntry;
turnReply.push({
urls: url,
password,
username,
});
});
const stDictionary = {
stun: stunServers.map(server => server.url),
turn: turnReply,
};
STUN_TURN_DICT = stDictionary;
return Promise.resolve(stDictionary);
};
const url = `${STUN_TURN_FETCH_URL}?sessionToken=${sessionToken}`;
return fetch(url, { credentials: 'include' })
.then(res => res.json())
.then(handleStunTurnResponse);
};
const mapStunTurn = ({ stun, turn }) => {
const rtcStuns = stun.map(url => ({ urls: url }));
const rtcTurns = turn.map(t => ({ urls: t.urls, credential: t.password, username: t.username }));
return rtcStuns.concat(rtcTurns);
};
const getFallbackStun = () => {
const stun = FALLBACK_STUN_SERVER ? [FALLBACK_STUN_SERVER] : [];
return { stun, turn: [] };
};
const getMappedFallbackStun = () => (FALLBACK_STUN_SERVER ? [{ urls: FALLBACK_STUN_SERVER }] : []);
const fetchWebRTCMappedStunTurnServers = function (sessionToken) {
return new Promise(async (resolve, reject) => {
try {
if (MAPPED_STUN_TURN_DICT && CACHE_STUN_TURN) {
return resolve(MAPPED_STUN_TURN_DICT);
}
const stDictionary = await fetchStunTurnServers(sessionToken);
MAPPED_STUN_TURN_DICT = mapStunTurn(stDictionary);
return resolve(MAPPED_STUN_TURN_DICT);
} catch (error) {
return reject(error);
}
});
};
export {
fetchStunTurnServers,
fetchWebRTCMappedStunTurnServers,
getFallbackStun,
getMappedFallbackStun,
};