团队大佬有点嫌弃原来p2p方案提供商,准备尝试使用webrtc评估替代可能性,所以近期开始架设webrtc的服务器。因为webrtc是一套通用协议,所以基于三方服务器进行通路测试及评估,先跑起来再逐步学习。基于技术栈就选以node接口的mediasoup这款开源服务器跑起来熟悉下套路。本文为Mediasoup demo部署说明。
Mediasoup官网:https://mediasoup.org
Mediasoup官方演示:https://v3demo.mediasoup.org
Demo git地址及部署说明:https://github.com/versatica/mediasoup-demo
文章目录
1 mediasoup简介
如果是用于多方会议,那WebRTC的服务器模型有两种,分别是SFU和MCU,这两类均为接入mediaserver的模式,所以实质上均为转发,不支持P2P。SFU实现的是简单转发的路由功能,而MCU可以提供更多扩展性的功能实现,而且MCU型的服务器往往包含SFU,所以MCU的实现难度较大。而本人主要目的是把webrtc用于物联网设备不会涉及到较为复杂的音视频处理,主要用于评估多方接入物联网设备可行性及稳定性,只会在mesh和SFU架构中进行考虑。
SFU模型:
MCU 模型:
Mediasoup号称领先的WebRTC的视频会议系统,具有以下特点:
- 强大的SFU功能,由于其多功能性,性能和可扩展性,mediasoup成为构建多方视频会议和实时流媒体应用程序的完美选择。
- mediasoup是一个Node.js模块,可以集成到更大的应用程序,便于集成
- mediasoup附带mediasoup-client(JavaScript库)和libmediasoupclient(C ++库),用于构建使用统一API在任何浏览器或设备中运行的应用程序。
具有SFU功能,可以支持扩展1对多,本身为node模块,很方便node技术栈接入,提供C++客户端的lib方便嵌入到嵌入式设备。 整体来说比较切合物联网技术栈。整个安装部署过程较为简单。
2 Demo 源码准备
下载源码:
git clone https://github.com/versatica/mediasoup-demo.git
cd mediasoup-demo
git checkout v3
安装server依赖:
源码根目录执行
cd server
npm install
超级久,有766M 过程中还有C++ 编译。
看着不动不要以为宕机了 确实在太大了……
如果顺利的话可以npm install 成功,这里有可能timeout,可参见后文处理方式。
cp config.example.js config.js
复制示例config为config 并修改其中配置
安装web app依赖:
源码根目录执行
cd app
npm install
npm install -g gulp-cli
3 部署及测试
3.1 本地测试
打开一个shell,源码根目录执行
cd server
DEBUG="*mediasoup* *ERROR* *WARN*" INTERACTIVE="true" node server.js
在另外一个打开一个shell
cd app
gulp live
执行该命令后,可以看到有一个提示地址3000端口,访问即可实现官方demo效果
3.2 服务器部署
本章节部署环境为VPS 公网ip即为服务器ip
源码根目录执行
cd app
gulp dist
执行后web app就被编译到了源码server目录pubilc目录下,现在server目录即为我们可以用来部署的源码。
1 将整个server文件夹上传到您的服务器,并使您的Web服务器(Apache,Nginx …)公开该server/public文件夹。
因为实质上web app是用react.js写的。所以我们这里以nginx的方式举例,在nginx.conf中添加一个server块
server {
listen 443;
server_name webrtc.xxx.top;
ssl_certificate /root/webrtc/mediasoup/mediasoup-demo/server/certs/webrtc.xxx.top.pem;
ssl_certificate_key /root/webrtc/mediasoup/mediasoup-demo/server/certs/webrtc.xxx.top.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl on;
location ~ .*?\.(js|css|jpg|png|jpeg|less|sass)
{
root /root/webrtc/mediasoup/mediasoup-demo/server/public;
}
location / {
root /root/webrtc/mediasoup/mediasoup-demo/server/public;
try_files $uri /index.html;
index index.html index.htm index.php;
}
}
打开ssl 配置相应域名证书,配置web app相应路由把server/pubilc 设置为静态资源以供访问。
重启nginx -s reload
2 配置config.js 配置server目录下的config.js
server/config.js使用适当的设置编辑您的(侦听IP /端口,日志记录选项,有效的 TLS证书等)。
修改https 块中的监听地址:
修改为自己服务器所在ip和tls证书位置(建议将证书放到server/certs 目录下):
listenIp :'144.34.123.22 ',
tls :
{
cert : ${__dirname}/certs/webrtc.xxx.top.pem
,
key : ${__dirname}/certs/webrtc.xxx.top.key
}
最后修改webRtcTransport
listenIps:修改为自己服务器地址所在ip地址。
3 启动及测试
然后使用node server.js 启动即可。
在服务器中,运行服务器端Node.js应用程序。我们建议使用pm2 NPM守护程序启动程序,但可以使用任何其他程序。
测试直接访问域名对应的地址既能实现和demo 网站一样的效果。
3.3 云主机部署
在在云主机部署与VPS部署稍有差异,因为云主机有内网ip。所以第二部中config.js需要稍作修改。
我们修改config 文件
listenIp 需修改为云主机内网ip ,因为云主机应该是不知道自己的公网ip的。
下方webRtcTransport块中listenIps 中内容更改为
{ ip: ‘内网ip’ , announcedIp:‘公网ip’ }
然后正常使用node server.js 启动即可
3.4 实际效果
直接访问地址ip即可 后面url有房间号 ,想加入同一房间填入即可。
三个设备接入实际效果,但通过firefox 的 about:webrtc调试确实看到没有p2p ,mediasoup作为webrtc peer接入到整个网络。
4 遇到的问题
4.1 server代码 npm install 超时 导致install失败
Downloading clang-tools-r298696-linux.tgz
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.2.9
Downloading clang-tools-r298696-linux.tgz
Error: read ECONNRESET
unziping undefined
tar (child): undefined: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
npm WARN lifecycle mediasoup@3.0.0-dev~postinstall: cannot run in wd %s %s (wd=%s) mediasoup@3.0.0-dev make -C worker /root/webrtc/mediasoup/mediasoup-demo/server/node_modules/mediasoup
mediasoup-demo-server@3.0.0 /root/webrtc/mediasoup/mediasoup-demo/server
报了上诉错误。看起来像是npm install 完了。强行run 一波
mediasoup:ERROR:Worker worker process failed [pid:undefined]: spawn /home/icatch/webrtc/mediasoup/server/node_modules/mediasoup/worker/out/Release/mediasoup-worker ENOENT +0ms
(node:2166) UnhandledPromiseRejectionWarning: Error: spawn /home/icatch/webrtc/mediasoup/server/node_modules/mediasoup/worker/out/Release/mediasoup-worker ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:232:19)
at onErrorNT (internal/child_process.js:407:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
(node:2166) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:2166) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
解决:
cd node_modules
rm -rf clang-tools-prebuilt
rm -rf mediasoup
npm install
重新安装 安装后node server.js 就可以跑起来了。(也需要装很久)