前言
对于一个外包项目或初创公司来说,如果想要在项目中实现音视频通话,诸如1V1视频通话,多人群通话或者类似Zoom那种多人在线音视频会议,选择的往往是第三方云服务,例如声网、腾讯云音视频等等,但是第三方云服务价格是昂贵的,对于初创公司或者外包项目来说代价太大,而想要实现本地云自建音视频通话服务,对于国内大多数独立开发者又是较为困难的,恰巧本人近两年的项目常涉及到通话和会议,经过调研了互联网上的各类型方案以及客户的主观经济原因,最终我们采用了Livekit
Livekit是一个基于WebRTC的开源音视频通话框架,其开源特性让我们可以在本地搭建整套程序,不需要第三方云服务的支持就实现完整的音视频通话流程,客户端支持多种SDK,包含Android、iOS、Web、Flutter等。
说这个不是打广告,只是相对外包或者独立开发者想要实现音视频通话,抛开第三方云服务之外,各类型资料和研究都相对较少,且相对复杂。而Livekit作为近两年的新起之秀,各方面相对完善,可以非常容易的实现音视频通话,发这个博客也是希望可以让更多的人以最小的代价接触音视频通话相关的业务。当然有好就有坏,Livekit在国内的文档和资料较少,且SDK目前迭代频率高,bug相对也多些,并且截止2025年2月,根据Github咨询,其官方暂未有客户端SDK支持鸿蒙的计划。
问题
博主大概是在2022年-2023年接触的Livekit,在项目开发的过程中遇到了不少问题,虽然也逐一解决,但确实是耗神耗力,最近客户的App流量有所上升,单机Livekit-Server有些捉襟见肘,遂记录以下分布式多节点部署方案。
Livekit Server 单机部署
注
- Livekit 是基于WebRTC开发,所以默认阅读者对WebRTC和Livekit有一定的了解,可以不深入,但是需要知道什么是WebRTC和Livekit以及通话部分原理和流程,建议阅读本文章前查看官网文档。
- 基于国内的电信网络环境,我们使用WebRTC必须有TURN Server,也就是媒体中转服务。它可以将我们的语音视频数据进行多方中转
准备
- 一台公网服务器,必须保证机房防火墙允许全部TCP UDP端口正常通信(或者自行查看官方文档需要开通的端口),注:测试可使用腾讯云服务器,博主在其平台测过无数次,无异常。
- 两个域名(子域名即可)
-
- 主域名
-
- TURN TLS域名
- 两个域名对应的ssl证书
- 服务端不建议在Windows上部署,博主以下操作均在Linux环境下执行
去除服务器443端口占用
保证当前服务器内443端口不被任何程序占用,因为Livekit Server要用
安装 Livekit Server
curl -sSL https://get.livekit.io | bash
如果国内服务器网络环境执行以上命令失误
可以去[Github Releases](https://github.com/livekit/livekit/releases)
下载对应服务器版本的程序上传到服务器解压,会得到一个程序[livekit-server],以上命令
也是去下载这个程序,只是少了移动到bin目录的操作。本博文编写时使用版本:1.8.3
启动运行
./livekit-server --config config.yaml --node-ip 8.8.8.8
Ubuntu系统请添加sudo
--node-ip 8.8.8.8 修改为你的外网IP
config.yaml
port: 7880
log_level: info
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
keys:
yhpbs: 26148d621ef74844918af182d63976b6
turn:
enabled: true
udp_port: 5161
tls_port: 443
domain: TURN TLS域名
cert_file: TURN TLS域名ssl证书绝对路径
key_file: TURN TLS域名ssl证书密钥绝对路径
以上config.yaml是我的配置,你也可以直接使用,关于完整的配置说明,可以去github.com/livekit/liv… 查看
关键配置说明
- keys是你的项目后端使用Server API SDK操作服务端API所需要的密钥键值对,可以多个,也可以直接修改我配置文件内的yhpbs和26148d621ef74844918af182d63976b6(我随便写的,你要直接用也行,不建议直接用,会泄露)
- Livekit Server内置了一个TURN Server,所以不需要我们再去搭建TURN Server,只需要配置一下参数即可使用,本人上面提供的config.yaml使用了内置的TURN。当然你也可以使用其他TURN服务器,在config.yaml里自行配置参数
turn_servers(内置的不需要这个参数),但是我不建议。因为经过本人多次测试,Livekit Server内置的TURN Server比自己搭建的TURN服务器网络质量至少提升三分之一(多次测试不同的自建TURN得出的结论,原因未知)。 - 关于内置的TURN Server,请根据本人提供的config.yaml中文提示进行输入对应的值
启动成功截图
安装Nginx
自行安装或者使用宝塔进行安装,假设我们已经在服务器上安装好了宝塔面板和Nginx
反代Livekit Server
- 使用宝塔创建项目,填入主域名
- 开启ssl,填入主域名证书
- 修改ssl端口为其他端口,比如4431
- 反代 Livekit Server 7880端口
此时我们可以通过浏览器访问一下:https://主域名:4431 如果证书正常、返回值ok,则表示反代成功
使用Nginx时需要保证Nginx不使用443端口,因为Livekit Server已占用
经过以上的操作,单机版Livekit Server就已经成功部署完成了。
验证Livekit Server是否正常通信
1. 生成Token
请先使用Server API SDK进行用户Token的生成,具体操作方式请查看官方文档
Server API SDK支持Java、PHP、Go和JavaScript等语言,一般项目都能使用。
api-key和secret-key在上述搭建Livekit Server的配置文件中已经填写(keys)
博主提供两个根据 yhpbs: 26148d621ef74844918af182d63976b6生成的Token,房间号相同均为:898989,有效期:2000天,生成日期:2025.02.05
user1:
eyJhbGciOiJIUzI1NiJ9.eyJtZXRhZGF0YSI6IntcInN0YXJ0UHVibGlzaFwiOmZhbHNlLFwidXNlckluZm9cIjp7XCJ1c2VySWRcIjpcInVzZXIxXCIsXCJuaWNrbmFtZVwiOlwiQUFcIixcImF2YXRhclwiOlwiaHR0cHM6Ly9pbWcyLndveWFvZ2V4aW5nLmNvbS8yMDIzLzA2LzIyLzVhMzg0NmQ5OWM5NzQxZGJiYjBiM2Y0ZWM0Y2NjOWYyLmpwZ1wifX0iLCJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6Ijg5ODk4OSIsImNhblVwZGF0ZU93bk1ldGFkYXRhIjp0cnVlfSwiaXNzIjoieWhwYnMiLCJleHAiOjE5MTE1NTAyOTgsIm5iZiI6MCwic3ViIjoidXNlcjEifQ.mTWFPKII0uxqyiHfYKkgkFlsAX91yrD6NJYiDPknxtM
user2:
eyJhbGciOiJIUzI1NiJ9.eyJtZXRhZGF0YSI6IntcInN0YXJ0UHVibGlzaFwiOmZhbHNlLFwidXNlckluZm9cIjp7XCJ1c2VySWRcIjpcInVzZXIyXCIsXCJuaWNrbmFtZVwiOlwiQUFcIixcImF2YXRhclwiOlwiaHR0cHM6Ly9pbWcyLndveWFvZ2V4aW5nLmNvbS8yMDIzLzA2LzIyLzVhMzg0NmQ5OWM5NzQxZGJiYjBiM2Y0ZWM0Y2NjOWYyLmpwZ1wifX0iLCJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6Ijg5ODk4OSIsImNhblVwZGF0ZU93bk1ldGFkYXRhIjp0cnVlfSwiaXNzIjoieWhwYnMiLCJleHAiOjE5MTE1NTAyOTEsIm5iZiI6MCwic3ViIjoidXNlcjIifQ.igOi4jOyNY6y8iSrlQy2aeL4MtUM0h5MSqVvc8ZW-mg
以下是一个JavaScript的获取Token案例,以供参考。
import express from 'express';
//根据官方文档安装livekit-server-sdk
import { AccessToken } from 'livekit-server-sdk';
const createToken = () => {
const room = '房间号';
const identity = '用户ID标识';
const at = new AccessToken('api-key', 'secret-key', {
identity: participantName,
});
at.addGrant({ roomJoin: true, room: room });
return at.toJwt();
};
const app = express();
const port = 3000;
app.get('/getToken', (req, res) => {
res.send(createToken());
});
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
2. Connection-Test
使用Livekit官方提供的验证工具:livekit.io/connection-…
推荐测试时使用火狐浏览器,重要!!!
- https://主域名:4431
- 用户Token
根据我画框的两处无报错,即可证明Livekit Server通信正常。如出现黄色、红色提示表明可能存在异常。
3. Livekit Meet
使用Livekit官方提供的Web端会议组件:meet.livekit.io/
Token生成时设置的房间号相同即进入相同的会议,进入会议后开启麦克风和摄像头观察是否正常。
4. 其他客户端SDK
请查看官方文档加载相关SDK依赖后调用
Livekit Server 分布式多节点部署
描述
Livekit Server仅需新增Redis参数,即可实现分布式部署,但是开源版本Livekit Server仅支持相同房间在同一个节点。
即Livekit分布式是将房间平均分到各个服务器,但是房间内的用户仅支持在同一个服务器。
我把他称之为【房间分布式】,而非【用户分布式】
比如: 【房间1】在服务器1,【房间1里有300人】,这300个用户在服务器1 【房间2】在服务器2,【房间2里有50人】,这50个用户在服务器2
并且截止2025.02.05日,根据Github咨询,Livekit开源版本暂未计划实现【用户分布式】,而【Livekit Cloud】天然支持(Livekit Cloud是其官方部署的Server),狗头警告🐶~
而【房间分布式】和【单机部署】都会在单房间内人数及带宽飙增的情况下,使单服务器成本上升,国内的大带宽服务器价格相对较高,基于上述外包项目和初创公司的状态下,虽比第三方云服务便宜,但也会随人数增多而增大开支。所以根据这种情况,开源版本Livekit Server不建议实现直播业务,但对于外包项目和初创公司来说,1v1通话、多人群通话、小规模会议(300人以下)是非常合适的。
准备
- Redis服务器
- 新的单机部署服务器
操作流程
- 根据以上【单机部署】流程,进行部署多台服务器,假设部署了两台【单机】Livekit Server
- 单域名DNS负载均衡解析或者根据自己项目决定多个域名,假设我们使用单域名负载均衡解析,将单域名解析到两台【单机】Livekit Server服务器的IP上
- 两台单机Livekit Server均修改config.yaml,新增Redis参数,具体如下:
port: 7880
log_level: info
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: false
redis:
address: 10.206.0.9:6379
password: redis666..
keys:
yhpbs: 26148d621ef74844918af182d63976b6
turn:
enabled: true
udp_port: 5161
tls_port: 443
domain: TURN TLS域名
cert_file: TURN TLS域名ssl证书绝对路径
key_file: TURN TLS域名ssl证书密钥绝对路径
- 重启两台服务器上的Livekit Server
- 测试,可使用
livekit-cli或者自行安排实际应用进行房间测试
测试结果
博主使用两台服务器、三个房间、每个房间五个视频流进行测试,结果如下:
根据图1可以发现,三个房间平均分布在了两个节点。图2图3分布代表服务器1和服务器2,且两台服务器带宽监控平均。
如上,分布式多节点部署完成。
关于更多Livekit遇到的问题,可以通过vx互相探讨:Sentinel-110