尝鲜:如何搭建一个简单的webrtc服务器

本文涉及的产品
.cn 域名,1个 12个月
简介: 前几天我一朋友问我有关webrtc的事,简单了解了下相关知识,搭建了一个webrtc的服务,以及经历的各种踩坑事件,感觉踩坑主要是Python、Node、OpenSSL等版本问题和证书问题导致。本来以为很简单的搭建,但在搭建的过程中遇到各种阻碍,写一篇文章梳理一下。

前言

前几天我一朋友问我有关webrtc的事,简单了解了下相关知识,搭建了一个webrtc的服务,以及经历的各种踩坑事件,感觉踩坑主要是Python、Node、OpenSSL等版本问题和证书问题导致。本来以为很简单的搭建,但在搭建的过程中遇到各种阻碍,写一篇文章梳理一下。

WebRTC 简介

WebRTC,名称源自网页即时通信(英语: Web Real-Time Communication )的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的 API。2010 年 5 月,Google 以 6820 万美元收购 VoIP 软件开发商 Global IP Solutions 的 GIPS 引擎,并改为名为 “WebRTC”。在 2011 年 6 月 1 日开源 WebRTC 并在 Google、Mozilla、Opera 支持下被纳入万维网联盟的 W3C 推荐标准。

WebRTC的Demo项目: https://github.com/webrtc/apprtc

基于 WebRTC 的 1v1 视频实时通话架构

从大的方面可以分为 3 部分:

1. WebRTC 终端
    负责音视频采集、编解码、NAT 穿越、音视频数据传输
2. Signal 服务器
    负责信令处理,如加入房间、离开房间、媒体协商消息的传递等
3. STUN/TURN 服务器
    负责获取 WebRTC 终端在公网的 IP 地址,以及 NAT 穿越失败后的数据中转

架构图:
WebRTC 1 对 1 音视频实时通话过程示意图

安装 WebRTC 服务器

运行环境准备

  • 操作系统:Ubuntu 16.04
  • 语言环境:NodeJS、Python、Golang
  • 其他软件:git、tar、wget、unzip

命令安装:

apt-get update 
apt-get upgrade
apt install -y nodejs-legacy npm python python-webtest golang-go unzip git-core tar wget

安装依赖服务

安装google_appengine:

cd /root/webrtc
wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip
unzip google_appengine_1.9.40.zip
echo "export PATH=$PATH:/root/webrtc/google_appengine" >> /etc/profile

安装libevent:

wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar xvf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure
make && make install

安装信令(Signal)服务

mkdir -p /root/webrtc/goWorkspace/src
echo "export GOPATH=/root/webrtc/goWorkspace" >> /etc/profile
source /etc/profile
cd /root/webrtc
git clone git://github.com/webrtc/apprtc.git
ln -s /root/webrtc/apprtc/src/collider/collider $GOPATH/src
ln -s /root/webrtc/apprtc/src/collider/collidermain $GOPATH/src
ln -s /root/webrtc/apprtc/src/collider/collidertest $GOPATH/src
go get collidermain
go install collidermain

安装STUN/TURN服务

cd /root/webrtc
wget http://coturn.net/turnserver/v4.5.0.7/turnserver-4.5.0.7.tar.gz
tar xvfz turnserver-4.5.0.7.tar.gz
cd turnserver-4.5.0.7
./configure
make install

安装WebRTC 终端服务

通过修改配置文件 /root/webrtc/apprtc/src/app_engine/constants.py来设备好ICE配置(与STUN/TURN服务交互)和WebSocket配置(与信令服务交互)。然后再

配置好ICE

ICE_SERVER_OVERRIDE  = [
   {
     "urls": [
      # 这儿要改成你自己启动STUN/TURN服务的外网IP
       "turn:47.105.214.21:3478?transport=udp",
       "turn:47.105.214.21:3478?transport=tcp"
     ],
      # 这儿要改成你设备的STUN/TURN服务的用户名和凭证
     "username": "flyer",
     "credential": "123456"
   },
   {
      # 这儿要改成你自己启动STUN/TURN服务的外网IP
     "urls": [
       "stun:47.105.214.21:3478"
     ]
   }
 ]
# 这儿要改成WebRTC 终端服务的请求地址
ICE_SERVER_BASE_URL = 'https://webrtc.zhaoweiguo.com'

配置好信令服务

# 这儿建议设置和WebRTC 终端服务同样的域名,否则要申请两个证书
WSS_INSTANCE_HOST_KEY = 'webrtc.zhaoweiguo.com:8089'
WSS_INSTANCE_NAME_KEY = 'vm_name'
WSS_INSTANCE_ZONE_KEY = 'zone'
WSS_INSTANCES = [{
    WSS_INSTANCE_HOST_KEY: 'webrtc.zhaoweiguo.com:8089',
    WSS_INSTANCE_NAME_KEY: 'wsserver-std',
    WSS_INSTANCE_ZONE_KEY: 'us-central1-a'
}]

安装相关依赖

# 1. 升级npm
npm install -g n
n stable
hash -r  #   (for bash, zsh, ash, dash, and ksh)
# or rehash   (for csh and tcsh)

# 2. 安装node构建工具:grunt
npm -g install grunt-cli@1.3.2

# 3. 安装 coffeescript
npm install --dev coffeescript

安装apprtc

cd /root/webrtc/apprtc
npm install --no-fund
grunt build

证书生成

生成私有证书

openssl req -x509 -out /cert/cert.crt -keyout /cert/key.pem \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=webrtc.zhaoweiguo.com' \
  && cat /cert/key.pem > /cert/cert.pem \
  && cat /cert/cert.crt >> /cert/cert.pem \
  && chmod 600 /cert/cert.pem /cert/key.pem /cert/cert.crt

# 注意:把-subj '/CN=webrtc.zhaoweiguo.com'中的域名改成你自己的域名

使用certbot生成免费的Let’s Encrypt证书

安装certbot:

# Debian
apt-get install certbot
# Docker
docker pull certbot/certbot

前提:

1. 执行此命令必须使用 root 用户获得文件夹的权限
2. 域名能访问并且有绑定的公网 IP
3. 必须在此域名绑定的服务器上运行

基于 Nginx 生成证书:

安装插件:
apt-get install python-certbot-nginx
执行命令:
$ sudo certbot certonly --nginx
  Saving debug log to /var/log/letsencrypt/letsencrypt.log
  Plugins selected: Authenticator nginx, Installer nginx

  Which names would you like to activate HTTPS for?
  - - - - - - - - - - - - - - - - - - - - - - - -
  1: zhaoweiguo.com
  2: knowledge.zhaoweiguo.com
  3: www.zhaoweiguo.com
  - - - - - - - - - - - - - - - - - - - - - - - -

选择你要生成证书的域名,根据提示一步步执行就好了

不基于webserver直接生成证书

1. 直接命令执行
certbot certonly --standalone --email admin@zhaoweiguo.com -d webrtc.zhaoweiguo.com
2. 使用Docker执行
docker run -it -p 80:80 --rm --name certbot \
    -v "/etc/letsencrypt:/etc/letsencrypt" \
    -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
    certbot/certbot certonly --standalone \
    --email admin@zhaoweiguo.com -d webrtc.zhaoweiguo.com

注意:80端口不可被占用,它会启动80端口的一个服务用于验证你的合法性

证书生成成功界面

- Congratulations! Your certificate and chain have been saved at:
 /etc/letsencrypt/live/webrtc.zhaoweiguo.com/fullchain.pem
 Your key file has been saved at:
 /etc/letsencrypt/live/webrtc.zhaoweiguo.com/privkey.pem
 Your cert will expire on 2023-03-19. To obtain a new or tweaked
 version of this certificate in the future, simply run certbot
 again. To non-interactively renew *all* of your certificates, run
 "certbot renew"
- If you like Certbot, please consider supporting our work by:
 Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 Donating to EFF:                    https://eff.org/donate-le

启动服务

设定环境变量

# 本地IP地址
export LOCAL_IP=xx.xx.xx.xx
# 外网IP地址
export SERVER_IP=xx.xx.xx.xx

启动STUN/TURN服务

nohup turnserver -L $LOCAL_IP -a -u flyer:123456 -v -f -r nort.gov &

检查是否启动成功:

lsof -i:3478
# 出现如下信息即为成功:
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
turnserve 14754 root   16u  IPv4 112232      0t0  UDP instance-5i00bk4l:3478 
turnserve 14754 root   17u  IPv4 112233      0t0  UDP instance-5i00bk4l:3478 
turnserve 14754 root   32u  IPv4 112263      0t0  TCP instance-5i00bk4l:3478 (LISTEN)
turnserve 14754 root   33u  IPv4 112267      0t0  TCP instance-5i00bk4l:3478 (LISTEN)

启动信令服务

启动命令:

cd /cert    # 这个目录里面有前面生成的域名证书和密钥
nohup $GOPATH/bin/collidermain -port=8089 -tls=true  -room-server="https://$SERVER_IP:8080" &

检查是否启动成功:

lsof -i:8089
# 出现如下信息即为成功:
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
colliderm 14817 root    3u  IPv6 112969      0t0  TCP *:8089 (LISTEN)

出现如下打印日志即为启动成功:

2022/03/11 02:09:00 Starting collider: tls = true, port = 8089, room-server=https://47.253.204.204:8080

启动WebRTC 终端服务

nohup dev_appserver.py --host=$LOCAL_IP /root/webrtc/apprtc/out/app_engine --skip_sdk_update_check &

这时候在你的浏览器输入 http://服务器公网IP:8080/ 如果能顺利打开,那么恭喜你环境算是基本搭建成功啦!!!

配置Nginx

upstream roomserver {
    server 本机ip:8080;
}
server {
    root /usr/share/nginx/html;
    index index.php index.html index.htm;
    listen      443 ssl;
    ssl_certificate /cert/cert.pem;
    ssl_certificate_key /cert/key.pem;
    server_name webrtc.zhaoweiguo.com;   // 改成你自己的域名
    location / {
        proxy_pass http://roomserver$request_uri;
        proxy_set_header Host $host;
    }
}

加载Nginx:

nginx -s reload

运行效果

打开浏览器,输入 https://webrtc.zhaoweiguo.com ,页面显示如下:

首页

点击连接(JOIN),后

等待对方连接页面

可以看到下面等待其他人加入的链接。使用另一台电脑(手机)浏览器打开这个链接(如图我自己手机打开)

准备连接页面

点击「JOIN」后,显示连接成功页面

连接成功页面

Docker版实现

如果你只想快速验证使用,最简单的方法是使用Docker方式,我已经把大部分的工作封装到 镜像zhaowg/webrtc:new2 中了,可以直接使用,不过使用时注意网络要使用Docker的宿主网络模式(host):

# 注:使用--net=host使用宿主网络模式,如果使用默认的bridge模式会多一层Nat转换
#   在使用STUN/TRUN时会有问题
docker run -e "SERVER_IP=xx.xx.xx.xx" -e "LOCAL_IP=172.17.0.2" --net=host  -it zhaowg/webrtc:new2 bash

按上面文档说明修改成你自己的的域名、证书、ip等信息,然后执行

./start.sh

踩坑记录

  1. WebSocket connection failed
打开连接页面点击「JOIN」时报下面错
WebSocket connection to 'wss://webrtc.zhaoweiguo.com:8089/ws' failed: 
  Error in connection establishment: net::ERR_CERT_AUTHORITY_INVALID
这时,「信令服务」日志报:
2022/03/11 02:13:22 http: TLS handshake error from 111.205.43.248:15029: remote error: unknown certificate
解决方案:
修改AppRTC服务的配置中的WSS_INSTANCE_HOST_KEY选项
即修改文件/root/webrtc/apprtc/src/app_engine/constants.py
把WSS_INSTANCE_HOST_KEY选项的值设置为对应证书的域名(而不是用IP)
  1. 各种OpenSSL问题
这种问题我的解决方案是使用指定的OS版本
比如这儿用Ubuntu 16.04
  1. Failed to execute 'pushState' on 'History'
运行都成功,但就是在点击连接时报错
解决方法是:
修改文件 ``./src/web_app/js/appcontroller.js`` 中的 ``AppController.prototype.pushCallNavigation_`` 函数
在此函数最开始增加一句代码:
roomLink = roomLink.replace("http", "https");
参考自:https://github.com/ISBX/apprtc-node-server/issues/7
  1. grunt build报错
原因:
  主要是npm、grunt版本问题
解决方法:
  升级npm,使用指定的grunt版本
  1. go get collidermain命令失败
原因:
collidermain依赖项目golang.org/x/net/websocket
而执行go get collidermain命令时,会请求golang.org/x/net/websocket
而这个请求在国内默认不可访问
解决方案:
1. 解决请求golang.org网站的问题
2. 执行如下命令
mkdir -p $GOPATH/src/golang.org/x/
cd $GOPATH/src/golang.org/x/
git clone git://github.com/golang/net.git net 
go install net

附录:Dockerfile文件内容

FROM ubuntu:16.04

RUN apt-get update && apt-get upgrade && apt install -y nodejs-legacy npm python python-webtest golang-go unzip wget git-core
RUN npm -g install grunt-cli@1.3.2
RUN mkdir -p /root/webrtc/goWorkspace/src && cd /root/webrtc && wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip && unzip google_appengine_1.9.40.zip
RUN wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz && tar xvf libevent-2.0.21-stable.tar.gz && cd libevent-2.0.21-stable && ./configure && make && make install

ENV GOPATH=/root/webrtc/goWorkspace
ENV PATH=$PATH:/root/webrtc/google_appengine

WORKDIR /root/webrtc
RUN git clone git://github.com/webrtc/apprtc.git && ln -s /root/webrtc/apprtc/src/collider/collider $GOPATH/src && ln -s /root/webrtc/apprtc/src/collider/collidermain $GOPATH/src && ln -s /root/webrtc/apprtc/src/collider/collidertest $GOPATH/src && go get collidermain && go install collidermain

RUN wget http://coturn.net/turnserver/v4.5.0.7/turnserver-4.5.0.7.tar.gz && tar xvfz turnserver-4.5.0.7.tar.gz && cd turnserver-4.5.0.7 && ./configure && make install

WORKDIR /root/webrtc/apprtc

RUN npm install -g n && n stable && 
RUN npm install --no-fund && npm install --dev coffeescript &&  grunt build

WORKDIR /root/webrtc

RUN echo "nohup turnserver -L $LOCAL_IP -a -u flyer:123456 -v -f -r nort.gov &" >> ./start.sh && echo 'nohup $GOPATH/bin/collidermain -port=8089 -tls=true  -room-server="https://$SERVER_IP:8080" &' >> ./start.sh && echo "nohup dev_appserver.py --host=$LOCAL_IP /root/webrtc/apprtc/out/app_engine --skip_sdk_update_check &" >> start.sh && chmod +x start.sh

参考

目录
相关文章
|
Web App开发
部署WebRTC音视频会议服务需要以下服务器和带宽配置
部署WebRTC音视频会议服务需要以下服务器和带宽配置
349 3
|
Web App开发 Docker ice
阿里云上搭建webRTC 服务器——Licode
阿里云上搭建webRTC 服务器——Licode 系统配置 阿里云服务器 Ubuntu 14.04.5 LTS Docker 环境搭建 在一台空的机器上搭建docker环境,先要安装docker,执行下面的命令即可: apt-get update apt-get install docker.
9521 0
|
Web App开发 JavaScript 测试技术
webrtc学习: 部署stun和turn服务器
webrtc的P2P穿透部分是由libjingle实现的.  步骤顺序大概是这样的:  1. 尝试直连. 2. 通过stun服务器进行穿透 3. 无法穿透则通过turn服务器中转.    stun 服务器比较简单.
8974 1
|
Web App开发 编解码 关系型数据库
互动直播之WebRTC服务器Kurento实战
先介绍Kurento的主要模块及Kurento的Docker安装方式,接着介绍了基于coturn项目的打洞服务器的安装及调试,最后介绍Kurento的demo调试。
3157 0
互动直播之WebRTC服务器Kurento实战
|
Web App开发 编解码 ice
即构自研WebRTC网关服务器架构实践
即构为什么要自研WebRTC网关服务器?我们从开源和自行研发的优劣势说起。
3915 0
|
Web App开发 计算机视觉
揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍
揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍 WebRTC生态系统是非常庞大的。当我第一次尝试理解WebRTC时,网络资源之多让人难以置信。本文针对webRTC媒体服务器和相关的开源项目(如kurento,janus,jitsi.org等)做一些介绍。
4720 0
|
Web App开发 API 流计算
WebRTC MCU( Multipoint Conferencing Unit)服务器调研
接触过的有licode、kurento. licode的缺陷:文档支持有限,licode的app client库只有js的 kurento的优势:文档齐全,Demo俱备,封装API比较齐全。它的主要特性:   Networked streaming protocols, including HTTP, RTP and WebRTC.
2079 0
|
Web App开发 JavaScript Java
关于谷歌webrtc源码国内镜像的使用问题,以及Kurento媒体服务器
 关于谷歌webrtc源码国内镜像的使用问题,以及Kurento媒体服务器 我周末搞了两天没搞出来码在国内有个镜像:https://source.
3015 0
|
4天前
|
弹性计算
阿里云2核16G服务器多少钱一年?亲测价格查询1个月和1小时收费标准
阿里云2核16G服务器提供多种ECS实例规格,内存型r8i实例1年6折优惠价为1901元,按月收费334.19元,按小时收费0.696221元。更多规格及详细报价请访问阿里云ECS页面。
37 9