simpleWebrtc 架设方案

近期架设一次webrtc另一种开源实现simplewebrtc用于学习webrtc整体实现及架构。现在单纯P2P架构的webrtc开源服务器已经很少了且近乎没有维护。大部分都是Webrtc SFU和MCU网络模型实现,但对于物联网设备一般情况下下都是一对一通话且P2P十分重要(转发服务器开销很大)。

开源实现里面稍微靠谱一点就是SimpleWebrtc方案了,但该方案也在18年中旬停止维护了,今天部署发现也是一堆坑。

本文基于ubuntu环境架设


1 Webrtc 链接建立流程

这里引用一下网易云信的架构图及基础流程说明来对webrtc链接建立进行介绍
image.png
1) WebRTC A通过Signal Server转发SDP OFFER到WebRTC B。WebRTC B做完本地处理以后,通过 Signal Server转发SDP ANSWER到A。
2)A、B同时向STUN Server发送Binding request请求自身的外网地址,并从STUN Server回包的MAPPED-ADDRESS中得到各自的外网地址;
3)A、B收集完内外网ICE Candidate,并通过Signal Server发送给对方;
4)双方开始做NAT穿越,互相给对方的ICE Candidate发送STUN Binding Request;
5)NAT穿越成功,A、B之间的P2P连接建立,进入媒体互通阶段。

从上文流程描述上既可以看到有三种角色参与webrtc通信流程,一般情况下可以理解为由三个部分组成:
STUN/TURN Server
Signal Server
WebRTC Client端(App Server)

信令服务器中需要配置turn 和stun 地址。stun 可以获取NAT后的地址从而建立连接,turn 可以在打洞失败情况下通过服务器转发保证功能正常, ice 是一个框架,可以包含 turn或stun等穿透协议。具体参考STUN, TURN, ICE介绍。
simplewebrtc 是一套webrtc 开源方案提供了WebRTC Client Server及信令服务器,使用它即可实现一个简单demo,并通过阅读实现流程,可熟悉webrtc通信建立过程。

2 架设过程

本文基于simplewebrtc进行架设,
打洞服务器:开源coturn 项目地址:https://github.com/coturn/coturn
信令服务器:simplewebrtc配套的signalmaster ** 项目地址:https://github.com/andyet/signalmaster
Web APP
simplewebrtc ** ** 项目地址:**https://github.com/andyet/SimpleWebRTC

2.1 coturn 服务器架设

P2P连接建立会涉及到三个概念:STUN, TURN,ICE

  • STUN(Session

    Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创建UDP通信。该协议由RFC 5389定义。
  • TURN(全名Traversal Using Relay NAT),是一种数据传输协议(data-transfer protocol)。允许在TCP或UDP的连在线跨越NAT或防火墙。TURN是一个client-server协议。TURN的NAT穿透方法与STUN类似,都是通过获取应用层中的公有地址达到NAT穿透。但实现TURN

    client的终端必须在通信开始前与TURN server进行交互,并要求TURN server产生"relay

    port",也就是relayed-transport-address。这时TURN server会创建peer,即远程端点(remote

    endpoints),开始进行中继(relay)的动作,TRN

    client利用relay port将数据发送至peer,再由peer转传到另一方的TURN client。
  • ICE 是一个用于在offer/answer模式下的NAT传输协议,主要用于UDP下多媒体会话的建立,其使用了STUN协议以及TURN 协议,同时也能被其他实现了offer/answer模型的的其他程序所使用,比如SIP(Session Initiation Protocol).

而coturn即由Google开源方案发展而来TURN和STUN
Server的免费开源实现。

安装

sudo apt-get install coturn

生成tls证书
因为coturn可以支持tls 所以这里需要生成一份用于tls通信的证书及密匙。

mkdir  pem
openssl req -x509 -newkey rsa:2048 -keyout ./pem/turn_server_pkey.pem -out ./pem/turn_server_cert.pem -days 1095 -nodes

-days 有效天数
-node 不加密密匙 加密密匙后则需要解压密码,需要填入部分信息,然后得到证书和密匙:turn_server_pkey.pem turn_server_cert.pem

编辑文件/etc/turnserver.conf配置TURN服务器。并将下下列配置相应修改后复制到文档末尾保存退出
下面配置参数在该文件中均有注释说明。可自行搜索阅读。

listening-device=eth0
listening-port=3478
tls-listening-port=5349
listening-ip=172.17.19.101
relay-device=eth0
relay-ip=172.17.19.101
external-ip=60.70.80.91/172.17.19.101
min-port=49152
max-port=65535
fingerprint
lt-cred-mech
realm=demo
use-auth-secret
static-auth-secret=12345
stale-nonce
cert=/home/usera/coturn/pem/turn_server_cert.pem
pkey=/home/usera/coturn/pem/turn_server_pkey.pem
no-loopback-peers
no-multicast-peers
mobility
no-cli

这里通过上诉使用到参数的相应注释可对照参考

listening-device=eth0           #本地监听网卡
listening-port=3478             #监听端口
tls-listening-port=5349        #tls监听端口 
listening-ip=172.17.19.101   #监听内网ip 如果本身网卡绑定的公网ip 则填为公网ip,若为AWS 阿里云等云主机则为内网ip
relay-device=eth0                # 本地用于转发的网卡设备    
relay-ip=172.17.19.101       #Relay 地址,用于turn服务器在穿透失败的情况下用于转发地址
external-ip=60.70.80.91/172.17.19.101      #如果是云主机 则需配置这样 且为云主机公网ip/内网ip 
min-port=49152                #relay用于转发端口 最小值   云主机 注意开安全组/防火墙 
max-port=65535               #relay用于转发端口 最大值  默认端口范围为49152 and 65535
fingerprint                            # turn 消息中使用指纹进行消息验证
lt-cred-mech                        #使用长期凭证机制 需要支持WebRTC服务器coTurn必须开启长期凭证机制
realm=demo                       #管理员用户登录域  必须用长期凭证机制或转变为REST API。
use-auth-secret                   # TURN REST API flag.  设置基于身份验证密匙的特殊授权选项的标志。、
static-auth-secret=north  # 仅用于turn rest api的“static”身份验证机密值(字符串)
stale-nonce                        #session寿命,默认为无限时间,配置后为600s
pkey-pwd =                     #密匙解压密码
cert=/home/ubuntu/pem/turn_server_cert.pem    #tls 证书路径
pkey=/home/ubuntu/pem/turn_server_pkey.pem #tls 密匙路径 
no-loopback-peers                       #禁用peer 回环地址 如(127.x.x.x and ::1).
no-multicast-peers                        #禁用peer 已知广播地址(224.0.0.0 and above, and FFXX:*).
mobility                                         #Mobility with ICE , MICE规格支持.  peer在网络之间移动时,端点必须更改其IP地址。 MICE即为解决该情况的方案
no-cli                                          #关闭turn 服务Cli支持

这里因为signalmaster信令服务器使用turn rest API 静态身份验证方式 与apprtc 有一定差异。所以直接配置的是use-auth-secret 和static-auth-secret=north 这两个参数而不是配置user=demo:12345 这种验证方式。

启动

启动及查看状态

先使用命令启动

sudo /usr/bin/turnserver -c /etc/turnserver.conf  -o -v

守护启动:
修改 /etc/default/coturn,把TURNSERVER_ENABLED=1的注释去掉。

sudo systemctl daemon-reload
sudo service coturn start

查看状态

service coturn status

image.png

测试

如果在云主机上运行请确认相应端口安全组已开放 比如实例中的3478
5349 的TCP UDP端口

测试STUN:

turnutils_stunclient -p 3478 60.70.80.91
  • 3478是STUN服务的监听端口
  • 60.70.80.91是启动STUN服务的IP地址

结果如下:这里能看到 UDP
reflexive addr 为当前网络的出口IP及端口

0: IPv4. UDP reflexive addr: 101.204.xxx.xxx:60040

测试TURN:

turnutils_uclient -v -t -T -W 12345 54.222.207.42

使用静态密码进行链接测试
-W:TURN REST API “plain text” secret.
这两个参数需与coturn中static-auth-secret保持一致

测试成功后打印类似于下面内容:

4: start_mclient: tot_send_msgs=10, tot_recv_msgs=10
4: start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000
4: Total transmit time is 3
4: Total lost packets 0 (0.000000%), total send dropped 0 (0.000000%)
4: Average round trip delay 68.300000 ms; min = 36 ms, max = 104 ms
4: Average jitter 24.000000 ms; min = 17 ms, max = 64 ms

到这里coturn部署完毕。

说明

1 作为turn/stun服务器对外提供服务器则肯定会涉及到身份验证相关内容,一种方案是使用使用数据库存储用户或Restful API向自有账户服务器验证。第二种就是简单粗暴设置密码验证。
2 在一些文章提到turnadmin 创建管理员账户
sudo turnadmin -a -u
用户名 -p 密码 -r 域名
因为coTurn还提供了一个HTTPS页面:可以进行一些系统设置,比如修改领域,查看用户等,admin用户就是用来访问这个页面。所以不需要的情况下不用执行该步骤。
3 coturn性能
coturn当用作ICE解决方案的一部分时,对于VoIP连接,此TURN服务器可以处理每个CPU的数千个同时呼叫(当使用TURN协议时)或仅使用STUN协议时的数万个呼叫。对于几乎无限的可扩展性,可以使用负载平衡方案。可以使用以下工具(一个或它们的组合)实现负载平衡:该方案由谷歌开源发展而来

2.2 信令服务器signalmaster

signalmaster 一个简单的信令服务器,供客户端连接并为WebRTC进行信令。

安装

本节需要node环境,因signalmaster 同样长期未维护,所以需要node版本降到8.16.0,且package.json中socket.io版本也需要修改为1.37

安装node环境并降级

apt install nodejs    #下载nodejs
nodejs -v             #查看版本
apt install npm       #下载npm 工具
sudo npm install -g n #下载node 版本管理工具n
n list                #查看有哪些版本可用 
sudo n  8.16.0        #切换版本到8.16.0
node -v               #查看版本,如果没有更新到,可以删掉原文件,手动把n模块安装的node链接过去。
sudo ln -s /usr/local/bin/node /usr/bin/node  #版本已经切换成功可不执行这步

下载signalmaster并配置依赖

git clone https://github.com/andyet/signalmaster.git # 下载源码
vi package.json   # 修改依赖 修改socket io版本为1.3.7
npm install     #安装依赖  确保当前node版本为8.16.0

配置signalmaster 参数
修改config/development.json 配置 支持ssl 及 stun 配置

"server": {
   "port": 8888,
   "/* secure */": "/* whether this connects via https */",
   "secure": true,
   "key": "/home/usera/certs/webrtc.xxxx.top.key",
   "cert": "/home/usera/certs/webrtc.xxxx.top.pem",
   "password": null
 },
 "rooms": {
   "/* maxClients */": "/* maximum number of clients per room. 0 = no limit */",
   "maxClients": 0
 },
 "stunservers": [
   {
     "urls": "stun::60.70.80.91:3478"
   }
 ],

 "turnservers": [
   {
     "urls": ["turn:60.70.80.91:3478"],
     "secret": "12345",
     "expiry": 86400
   }
  • Secure 是否支持ssl
  • Key 证书密匙路径
  • Cert 证书路径
  • Stunservers stun服务器地址
  • Turnservers turn服务器地址
  • turn服务器身份验证:secret 为turn服务器中设置的静态密码 如:static-auth-secret=12345

这里如果不配置这些参数,会导致信令报错。建议直接使用域名加证书的方式启动信令服务器

启动

npm start

打印

&yet -- signal master is running at: http://localhost:8888

说明启动成功。

测试

http://localhost:8888/socket.io/

访问地址得到下列放回即为部署成功。PS:云主机中则需要开启8888端口及用云主机ip替换掉localhost。
返回如下 内容signal master 已经工作起来

{"code":0,"message":"Transport unknown"}

说明

node版本不降 会导致错误:
validation.target.mk:102:
recipe for target ‘Release/obj.target/validation/src/validation.o’ failed
Socket.io使用最新版会导致
TypeError: Cannot read
property ‘resources’ of undefined

2.3 SimpleWebrtc

安装

下载源码安装依赖

git clone https://github.com/andyet/SimpleWebRTC.git  #下载源码
npm install                                           #安装依赖

修改源码
修改simplewebrtc-with-adapter.bundle.js:

vi out/simplewebrtc-with-adapter.bundle.js

反向搜索url参数: SimpleWebRTC 构造函数中this.config中 修改url为信令服务器地址
搜索iceServer参数修改为2.1中coturn地址: iceServers: [{‘urls’: ‘stun:地址:3478’}]

修改test/index.html :

vi test/index.html

test/index.html 中引用了Google路径Jquery代码,国内无法访问会导致界面卡住。可以将这个JQuery 在线引用改为百度cdn地址
将地址:
https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js 改为https://libs.baidu.com/jquery/1.9.0/jquery.min.js

修改package.json:
将scripts 中 test-page 中stupid-server -s 后加入证书及密匙路径 以支持https。

stupid-server -s  -c /home/usera/certs/webrtc.xxx.top.pem  -k /home/usera/certs/webrtc.xxx.top.key  -h 0.0.0.0

启动

npm run test-page

打印以下内容启动成功:
open https://0.0.0.0:8443/test/
Listening on 0.0.0.0:8443…

测试

两端使用笔记本和手机进行测试,均使用firefox浏览器测试

https://60.70.80.91:8443/test/

填入公网ip访问 ,请填入自己云服务器公网ip。这里可能会报证书错误,适应被没有配置ssl证书 直接忽略警告继续访问。
两端填入同一房间建立链接
测试效果如下:
建立链接前:
Screenshot_2019-06-05-14-58-53-098_org.mozilla.firefox.png
建立链接后:
Screenshot_2019-06-06-11-20-02-137_org.mozilla.firefox.png

说明

默认设置情况下每路码流码流大约在2Mbps,网络较好情况下,时延在300~400ms(p2p - relay)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章