最近几天真的是全部忙碌在架设 WebRTC 的开源实现,想实现 Coturn + SignalMaster + WebRTC 这样的组合。在这几天,真的是走过了无数的坑。因为环境和不同博主的教程的原因,从云服务器换到本地主机,再从本地主机换回到服务器,同样的文件不同的人有不同的配置,真的是头都晕了,腰酸背痛,主要还是我太菜!
不过还好,最终踏平了所有的坑,看到系统成功跑起来的那一刻,真的是特别开心。
首先来瞅一眼 WebRTC 是什么。根据百度百科的定义:
WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持 网页浏览器 进行实时语音对话或视频对话的 API。
根据上面的定义我们可以知道,WebRTC 本质上就是一个 API。
那么只要实现这样的 API,我们就可以实现在网页浏览器上进行实时语音或者视频对话。WebRTC 采用独特的端到端媒体流,其中语音、视频和数据连接都直接在两个浏览器或 WebRTC 应用之间建立。但是,由于存在网络地址转换(NAT)和防火墙,增加了这一技术的实施难度,需要采用特殊的协议和过程才能实现。
于是就出现了下面这几个协议:
为了解决 IPV4 地址不够使用的问题,出现了 NAT 技术。NAT 的原理就是给一个 NAT 设备分配一个公网 IP 地址,NAT 设备背后的节点都将被分配私网 IP 地址,这样几十上百台节点只需要占用一个公网 IP 即可。那么对端如果只知道目标节点的公网 IP,将信息发到 NAT 设备中,那么 NAT 设备又是如何将信息发送到对应的节点的呢?
我们知道:通过 IP + 端口号
可以唯一的标识一个节点。在 NAT 设备中有一个地址映射表,这个表将公网的 IP + 端口号
的组合映射到了私网的 IP + 端口号
,如此就实现了内网穿透。
但是,现实的情况是:并不是每一个地址穿透都是成功的,在有些时候可能因为映射关系的外网数据包被丢弃了等其他一些复杂的原因,是无法实现成功穿透内网的。于是就相继出现了 STUN、TURN、ICE。
STUN 是一种客户端/服务器协议,允许内网的主机向外网的 STUN 服务器查询自己的公网 IP 和端口号。可以将 STUN 理解为一面照妖镜,内网主机可以通过这面镜子看到自己的真实信息(公网 IP + 端口号)。这些信息被用来在两个同时处于 NAT 路由器之后的主机之间创建 UDP 通信。
TURN 协议是对 STUN 协议的扩展,用于在 STUN 穿透失败的时候,提供媒体中继。其背后原理是:TURN Server 是一个具有公网 IP 的节点,发送端的主机是肯定可以直接找到公网中的节点并发送数据给它的,TURN Server 在收到发送端的数据后,会缓存发送给接收端。
ICE 协议是 STUN 协议和 TURN 协议的结合,它利用 STUN 协议和 TURN 协议实现建立 P2P。
其通过定期发送数据包来提供长连接功能:
SDP 全称是 Session Description Protocol,翻译过来就是描述会话的协议。它主要用于两个会话实体之间的媒体协商。
SDP 是纯粹的会话的描述格式而不是一个传输协议。它可以使用不同的传输协议,包括会话通知协议(SAP)、会话初始协议(SIP)、实时流协议(RTSP)、MIME 扩展协议的电子邮件以及超文本传输协议(HTTP)。SDP 并不描述广播地址的分配或者详细的消息描述,并且SDP也不是为沟通媒体编解码而设计的。
SDP的目的是传送多媒体会话中的媒体流的信息,以使会话描述的接收者可以参加会话。所以,SDP应该包含足够的信息来发起会话或使接收者加入会话。
SDP 应该包含:
WebRTC 没有实现信令机制,使得程序可以更加灵活,我们可以根据自己的需求自定义信令。信令有多种实现方式,可以使用已有信令,比如 SIP,也可以通过自定义实现信令,比如通过 WebSocket 实现信令机制。
在安装 Coturn 之前,首先需要准备好环境。
安装 openssl 和 libevent2
yum install -y openssl openssl-devel
yum install -y libevent-devel
安装 git
yum install -y git
以上就是安装 Coturn 阶段我们需要准备好的环境。
从 github 上下载最新版的 Coturn,我这里是下载到
git clone https://github.com/coturn/coturn.git
编译安装 Coturn
cd coturn
./configure
make && make install
查看 Coturn 是否安装成功
which turnserver
出现上图说明成功安装。
运行如下命令生成签名证书
openssl req -x509 -newkey rsa:2048 -keyout /etc/turn_server_pkey.pem -out /etc/turn_server_cert.pem -days 99999 -nodes
其中,部分参数的意义如下:
根据上面的命令指定的路径,我们可以知道将在 /etc
目录下生成 turn_server_pkey.pem
、turn_server_cert.pem
这两个文件。
查看文件
ls -la /etc/turn_*
可以看到,在 /etc
目录下生成了两个 .pem
文件。
在 /usr/local/etc/
目录下有 turnserver.conf.default
,将它复制为 turnserver.conf
cp /usr/local/etc turnserver.conf.default turnserver.conf
查看一下内网地址以及网卡名称
ifconfig
修改配置文件 turnserver.conf
vim /usr/local/etc/turnserver.conf
在配置文件的末尾加上如下内容
listening-device=eth0 # 刚刚查到的网卡名称
listening-port=3478 # Conturn 监听的端口号
tls-listening-port=5349
listening-ip=172.24.33.241 # 内网IP
relay-device=eth0 # 刚刚查到的网卡名称
relay-ip=172.24.33.241 # 内网IP
min-port=49512
max-port=65535
external-ip=39.106.197.250/172.24.33.241 # 公网IP/内网IP
fingerprint
lt-cred-mech
realm=ronz.top # 域名
user=neu:123456
stale-nonce
no-loopback-peers
no-multicast-peers
mobility
no-cli
cert=/etc/turn_server_cert.pem # 刚刚生成的签名证书
pkey=/etc/turn_server_pkey.pem
修改完毕,保存退出即可。
命令行输入如下命令启动 turnserver
turnserver -o -a -f -r ronz -c /usr/local/etc/turnserver.conf
测试 turnserver
turnserver 为我们提供了测试工具 trunutils_stunclient
、turnutils_uclient
。
至此,turnserver 搭建完毕。
SinalMaster 的运行需要 Node.Js 环境,所以在这里需要安装 Node。
至此,Node.Js 环境安装成功。
下载源码文件
git clone https://github.com/andyet/signalmaster.git
安装依赖
npm install
下面需要修改 signalmaster/config/development.json
的配置使其支持 ssl 并且配置 stun 及 turn。
{
"isDev": true,
"server": {
"port": 8888,
"/* secure */": "/* whether this connects via https */",
"secure": true,
"key": "/usr/lab_project/4666031_ronz.top.key",
"cert": "/usr/lab_project/4666031_ronz.top.pem",
"password": null
},
"rooms": {
"/* maxClients */": "/* maximum number of clients per room. 0 = no limit */",
"maxClients": 0
},
"stunservers": [
{
"urls": "stun:39.106.197.250:3478"
}
],
"turnservers": [
{
"urls": ["turn:39.106.197.250:3478"],
"username": "neu",
"credential": "123456",
"expiry": 86400
}
]
}
其中,这些参数需要着重注意:
server.port
: 信令服务器监听的端口号server.secure
: 连接是否由 HTTPS 发起server.key
: 自己申请的 SSL 的私钥(.key 文件)所在的路径server.cert
: 自己申请的 SSL 证书(.pem 文件)所在的路径stunservers.urls
: stun 服务器的地址turnservers.urls
: turn 服务器的地址turnservers.username
: 上面配置的 turnserver 的用户名turnservers.credential
: 上面配置的 turnserver 的密码启动信令服务器
cd signalmaster/
npm start # 等同于 node server.js
出现如下界面说明启动成功:
测试。
浏览器访问 https://39.106.197.250:8888/socket.io/,看到如下页面则说明信令服务器部署成功。
下载源码安装依赖
git clone https://github.com/andyet/SimpleWebRTC.git # 下载源码
npm install # 安装依赖
修改源码
对 SimpleWebRTC/out/simplewebrtc-with-adapter.bundle.js
做出如下修改:
修改 SimpleWebRTC/test/index.html
:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js">script>
<script src="https://cdn.bootcss.com/jquery/1.9.0/jquery.min.js">script>
修改 package.json
:
在 scripts
中的 test-page
中的 stupid-server -s
后加入证书以及密匙路径以支持 HTTPS。
"test-page": "echo \"open https://0.0.0.0:8443/test/\" && stupid-server -s -c ./4666031_ronz.top.pem -k /etc/httpd/cert/4666031_ronz.top.key -h 0.0.0.0",