Contains the code for the SFU (Selective Forwarding Unit) server used in Odoo Discuss. The SFU server is responsible for handling the WebRTC connections between users and providing channels to coordinate these connections.
The server is not stand-alone, it does not serve any HTML or any interface code for calls. It only contains the SFU and a client bundle/library to connect to it.
The SFU uses Mediasoup WebRTC library for the routing/transport of streams.
- Node.js 24.13.0 (LTS)
- FFmpeg 8 (if using the recording feature)
Build the client bundle
npm install
npm run buildOnce the bundle is built, it can be added to the assets of your main server, and interacted with as described here.
- Install dependencies.
npm ci -omit=dev
- Run the SFU server.
npm PROXY=1 PUBLIC_IP=sfu.example.com AUTH_KEY=u6bsUQEWrHdKIuYplirRnbBmLbrKV5PxKG7DtA71mng= run start
The available environment variables are:
| Variable | Default | Description |
|---|---|---|
PUBLIC_IP (required) |
- | Used to establish WebRTC connections to the server. |
AUTH_KEY (required) |
- | The base64 encoded encryption key used for JWT authentication. |
HTTP_INTERFACE |
0.0.0.0 |
HTTP and WebSocket listening interface. |
PORT |
8070 |
Port for HTTP and WebSocket. |
RTC_INTERFACE |
0.0.0.0 |
Interface address for RTC. |
PROXY |
false |
Set to true if behind a proxy to trust forwarding headers. |
AUDIO_CODECS |
All | Comma separated list of audio codecs to use (e.g., opus,PCMU,PCMA). |
VIDEO_CODECS |
All | Comma separated list of video codecs to use (e.g., VP8,H264,VP9). |
RTC_MIN_PORT |
40000 |
Lower bound for the range of ports used by the RTC server (TCP/UDP). |
RTC_MAX_PORT |
49999 |
Upper bound for the range of ports used by the RTC server (TCP/UDP). |
NUM_WORKERS |
CPU count | Number of mediasoup workers to spawn. |
MAX_BUF_IN |
0 (unlimited) |
Maximum incoming buffer size in bytes for SCTP messages per session. |
MAX_BUF_OUT |
0 (unlimited) |
Maximum outgoing buffer size in bytes for SCTP messages per session. |
MAX_BITRATE_IN |
8000000 |
Maximum incoming bitrate in bps per session (upload). |
MAX_BITRATE_OUT |
10000000 |
Maximum outgoing bitrate in bps per session (download). |
MAX_VIDEO_BITRATE |
4000000 |
Maximum bitrate in bps for the highest simulcast video layer. |
CHANNEL_SIZE |
100 |
Maximum amount of concurrent users per channel. |
LOG_LEVEL |
error |
SFU log level (none, error, warn, info, debug, verbose). |
LOG_TIMESTAMP |
true |
Prefix timestamps to log lines. |
LOG_COLOR |
TTY detection | Colors log lines based on their level. |
DEBUG |
- | Used by the debug module (e.g., DEBUG=*). |
WORKER_LOG_LEVEL |
none |
Mediasoup worker log level. Requires DEBUG to be active. |
DATA_PATH |
/tmp/odoo_sfu |
Base path for SFU local storage (recordings, resources, debug subfolders). |
The resources, recordings and debug directories under DATA_PATH must share
one filesystem mount. Recording finalization uses filesystem renames, which fail
with EXDEV across mounts.
Recording specific env variables:
| Variable | Default | Required | Description |
|---|---|---|---|
RECORDING |
false |
No | Enables the recording feature. |
LOCAL_KEY |
Randomly generated | No | 32-byte base64 key for encrypting local data. If missing, data loses persistence between restarts. |
DYNAMIC_MIN_PORT / DYNAMIC_MAX_PORT |
50000 / 59999 |
No | Range of ports used for recording routing. |
RECORDING_RESERVATION_MB |
Automatic worst case | No | Positive disk-space admission estimate per recording in MB (1 MB = 1,000,000 bytes). Overrides the estimate based on maximum duration, stream count and bitrates. |
FFMPEG_LOGGING |
false |
No | If true, generates .log files alongside ffmpeg outputs and archives processed recordings under ${DATA_PATH}/debug. |
RECORDING_RESERVATION_MB controls the free-space check when a recording starts.
It is an admission estimate, not a disk quota.
See config.ts for more details.
Set the AUTH_KEY env variable with the base64 encryption key that can be used to authenticate connections to the server.
Go to the Discuss settings and configure the RTC Server URL and RTC server KEY fields. The RTC server KEY
must be the same base64 encoded string as AUTH_KEY on the SFU server. Or pass the as env variables (ODOO_SFU_URL and ODOO_SFU_KEY).
The SFU server responds to the following IPC signals:
SIGFPE(8): Restarts the server.SIGALRM(14): Initiates a soft reset by closing all sessions, but keeps services alive.SIGIO(29): Prints server statistics, such as the number of channels, sessions, bitrate.
See server.ts for more details.