在上一篇文章中,我们介绍了如何构建信令服务器。但是信令服务器是如何工作的呢?哪些消息需要信令服务器控制和传输?这些之前都没有详细解释过,但本文会详细讨论这些问题。
![web服务器的架设(docker架设web服务器)插图 web服务器的架设(docker架设web服务器)插图](/uploads/image/pitem/628258c5094754312998c121.jpg)
另一方面,webrtc如何穿越真实网络中的nat?如果穿越不成功,如何保证用户服务?这些知识也将在本文中得到解答。
发信号
webrtc信令控制的架构图如下:
信令服务器用于交换三种类型的信息:
会话控制消息:初始化/关闭、各种业务逻辑消息和错误报告。
相关:可外部识别的ip地址和端口。
媒体能力:客户端可以控制的编解码器、分辨率以及它想与谁通信。
下面让我们详细讨论这三种类型的消息:
会话控制消息
会话控制消息很简单,比如创建和销毁房间、加入房间、离开房间、打开/关闭音频、打开/关闭视频等等。
对于一个真正的商业webrtc信令服务器,有很多会话控制消息。获取房间中的人数、静音/取消静音、切换扬声器、视频轮询、白板中的画笔、各种模式等。但都是比较简单的新闻。
在我们前面的例子中,服务器只处理一个会话消息create或join,即创建和加入房间的消息。代码如下:
…socket.on('create or join', function(room) { var clientsinroom = io.sockets.adapter.rooms[room]; var numclients = clientsinroom ? object.keys(clientsinroom.sockets).length : 0; if (numclients === 0) { socket.join(room); logger.debug('client id ' socket.id ' created room ' room); socket.emit('created', room, socket.id); } else if (numclients === 1) { io.sockets.in(room).emit('join', room); socket.join(room); socket.emit('joined', room, socket.id); io.sockets.in(room).emit('ready'); } else { // max two clients socket.emit('full', room); }}); …
这段代码的逻辑非常简单。收到创建或加入消息后,判断房间中的当前人数。如果房间里的人数是0,说明第一个人进来了。此时,您需要将创建的消息发送到连接的客户端。如果房间人数为1,说明第二个人进来,需要向客户端发送加入消息;否则发送满员信息,表示房间已满,因为目前一个房间只允许两个人。
网络信息消息
网络消息用于在两个客户端之间交换网络信息。在webrtc中使用ice机制建立网络连接。
在webrtc的每一端,当创建rtcpeerconnection对象并调用setlocaldescription方法时,收集ice候选项。
webrtc中有三种类型的候选人。它们是:
主持人候选人
反射候选
接力候选人
候选主机,指明本地局域网中的ip地址和端口。它在三个候选者中优先级最高,也就是说在webrtc的底层,它会首先尝试在本地局域网中建立连接。
反射候选,即获取nat中主机的外部ip地址和端口。其优先级低于宿主候选。也就是说,webrtc尝试本地连接时,会尝试通过反射候选获取的ip地址和端口进行连接。
其结构如下图所示:
上图可以看到,webrtc通过stun服务器获取自己的外网ip和端口,然后通过信令服务器与远程webrtc交换网络信息。之后双方可以尝试建立p2p连接。
以上就是我们通常所说的p2p nat穿越。在webrtc中,会检测用户的nat类型,最后采用不同的方法进行nat穿越。但如果双方都是对称nat类型,就无法穿越p2p nat,所以此时只能使用中继。
中继候选指示中继服务器的ip地址和端口,即媒体数据通过服务器传输。当webrtc客户端通信双方都无法穿越p2p nat时,为了保证双方的正常通信,只能通过服务器转移来保证服务质量。
所以中继候选的优先级最低,只有在以上两个候选都无法连接的情况下才会使用。
在webrtc信令服务器上,当接收到网络消息信令,也就是message消息时,会直接转发,不做任何处理。代码如下:
socket.on('message', function(message) { socket.broadcast.emit('message', message);});
客户端收到message消息后,会做出进一步的判断。如果消息类型为候选,即网络消息信令,则会生成一个rtcicecandidate对象,并添加到rtcpeerconnection对象中,这样webrtc就可以在底层自动建立连接。其代码如下:
socket.on('message', function(message) { … } else if (message.type === 'candidate') { var candidate = new rtcicecandidate({ sdpmlineindex: message.label, candidate: message.candidate }); pc.addicecandidate(candidate); } else if (…) { … }});
交换媒体能力消息
在webrtc中,媒体能力最终通过sdp呈现。在传输媒体数据之前,我们应该首先协商媒体能力,看看双方都支持哪些编码方法和分辨率。协商方法是通过信令服务器交换媒体能力信息。
过度采用webrtc媒体协商如上图所示。
在第一步中,amy调用createoffer方法来创建要约消息。offer消息中的内容是amy的sdp信息。
其次,amy调用setlocaldescription方法保存本地终端的sdp信息。
步骤3: amy通过信令服务器向bob发送offer消息。
第四步:收到offer消息后,bob调用setremotedescription方法存储它。
步骤5: bob调用createanswer方法来创建应答消息。同样,回答消息的内容是bob的sdp信息。
步骤6,bob调用setlocaldescription方法保存本地终端的sdp信息。
步骤7: bob通过信令服务器将anwser消息发送给amy。
第八步:amy收到anwser消息后,调用setremotedescription方法并保存。
通过以上步骤,完成了通信双方之间的媒体能力交换。
第一,信令服务器要处理的所有消息,这些消息构成了信令服务器最基本的信令,是必不可少的,否则双方将无法进行最终的通信。
在webrtc通信中,仅有信令是不够的。因为webrtc真正要传输的是媒体数据,信令只是其中的一部分。在webrtc中,他会尽可能的通过p2p传输数据,但是p2p穿越不成功怎么办?
然后您需要通过媒体中继服务器转发媒体数据。让我们来看看如何构建媒体中继服务器。
设置眩晕/转身
在公网上设置stun/turn服务并不难。首先要有云主机。如果有云主机,我就不介绍了。去云厂商买就行了。
目前流行的stun/turn服务器是coturn,搭建stun/turn服务非常方便。
让我们来看看它的基本步骤:
获取返回源代码
git clone https://github.com/coturn/coturn.git
编译并安装
cd coturn ./configure –prefix=/usr/local/coturn sudo make -j 4 && make install
配置转弯
网上有很多关于coturn的配置文章,非常复杂。大部分人都是从网上复制转发的,里面有很多错误。其实用coturn的默认设置就好了。我在这里整理了一份,如下:
listening-port=3478 #指定侦听的端口 external-ip=39.105.185.198 #指定云主机的公网ip地址 user=aaaaaa:bbbbbb #访问 stun/turn服务的用户名和密码 realm=stun.xxx.cn #域名,这个一定要设置
所以,只要把上面4行配置项写入/usr/local/co turn/etc/turn server . conf配置文件,你的stun/turn服务就配置好了。
启动眩晕/转身服务
cd /usr/local/coturn/bin turnserver -c ../etc/turnserver.conf
测试眩晕/转身服务
打开trickle-ice,按照里面的要求输入stun/turn地址,用户,密码,然后就可以检测stun/turn服务是否正常了。
以我们的配置为例,输入的信息是:
stun或turn uri的值是:turn:stun.xxx.cn
用户名:aaaaaa
密码:bbbbbb
测试结果如下图所示:
从上图可以看出,这个服务提供了stun(srflx)和turn(relay)服务。
部署了stun/turn之后,我们就可以用它来传输多媒体数据了,再也不怕因为nat和防火墙导致双方无法沟通的问题了。
总结
本文首先详细介绍了三种类型的webrtc信令消息的控制和交换。然后给出了stun/turn服务器的部署和配置以及如何测试。
这里需要强调的是,虽然stun/turn的部署非常简单,和webrtc一样,但是背后的原理却非常复杂。由于篇幅原因,这里没有给大家详细介绍。有兴趣的同学可以把它作为深入研究的起点。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文链接:https://www.andon8.com/3386.html