本文将向大家介绍两个方面的知识:
  • WebRTC信令控制
  • STUN/TURN服务器的搭建
在前面的文章中已经向大家介绍了如何构建信令服务器。但构建的信令服务器是如何工作的?哪些消息需要信令服务器控制和中转?
另一方面,在真实的网络中,WebRTC是如何进行NAT穿越的呢?如果穿越不成功,我们又该如何保证服务?
信令
WebRTC 信令控制架构图
signal.png834×520 47.5 KB
信令服务器用于交换三种类型的信息:
  • 会话控制消息:初始化/关闭,各种业务逻辑消息以及错误报告。
  • 网络相关:外部可以识别的IP地址和端口。
  • 媒体能力:客户端能控制的编解码器、分辩率,以及它想与谁通讯。
会话控制消息
会话控制消息比较简单,像房间的创建与销毁、加入房间、离开房间、开启音频/关闭音频、开启视频/关闭视频等等这些都是会话控制消息。
还有许多的会话控制消息。像获取房间人数、静音/取消静音、切换主讲人、视频轮询、白板中的画笔、各种图型等等。但相对来说都是比较简单的消息。
在我们之前的例子中,服务端只处理了一个会话消息 create or 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); } }); ...
该代码的逻辑非常简单,当收到 create or join 消息后,判断房间里当前人数,如果房间里的人数为 0,说明是第一个人进来,此时,需要向连接的客户端发送 created 消息;如果房间里的人数为 1,说明是第二个人进来,需要向客户端发送 joined消息;否则发送 full 消息,说明房间已满,因为目前一个房间最多只允许有两个人。
网络信息消息
网络信息消息用于两个客户端之间交换网络信息。
在WebRTC中使用 ICE 机制建立网络连接。
在WebRTC的每一端,当创建好 RTCPeerConnection 对象,且调用了setLocalDescription 方法后,就开始收集 ICE候选者 了。
在WebRTC中有三种类型的候选者,它们分别是:
  • 主机候选者
  • 反射候选者
  • 中继候选者
主机候选者,表示的是本地局域网内的 IP 地址及端口。它是三个候选者中优先级最高的,也就是说在 WebRTC 底层,首先会尝试本地局域网内建立连接。
反射候选者,获取 NAT 内主机的外网IP地址和端口。其优先级低于 主机候选者。也就是说当WebRTC本地连接不通时,会通过反射候选者获得的 IP地址和端口进行连接。
其结构如下图所示:
stun.png834×520 72.5 KB
在上面这幅图中可以看到,WebRTC通过 STUN server 获得自己的外网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 消息后,会做进一步判断。如果消息类型为 candidate,即 网络消息信令时,会生成 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 呈现。在传输媒体数据之前,首先要进行媒体能力协商,看双方都支持那些编码方式,支持哪些分辨率等。协商的方法是通过信令服务器交换媒体能力信息。
offer_answer.png1077×433 49.4 KB
WebRTC 媒体协商的过种如上图所示。
  • 第一步,Amy 调用 createOffer 方法创建 offer 消息。offer 消息中的内容是 Amy 的 #指定侦听的端口 external-ip=39.105.185.198 #指定云主机的公网IP地址 user=aaaaaa:bbbbbb #访问 stun/turn服务的用户名和密码 realm=stun.xxx.cn #域名,这个一定要设置
所以,只需将上面 4 行配置项写入到 /usr/local/coturn/etc/turnserver.conf 配置文件中,你的 stun/turn 服务就配置好了。
  • 启动 stun/turn 服务
cd /usr/local/coturn/bin turnserver -c ../etc/turnserver.conf
  • 测试 stun/turn 服务
打开 trickle-ice ,按里面的要求输入 stun/turn 地址、用户和密码后就可以探测stun/turn服务是否正常了。
以我们的配置为例,输入的信息分别是:
  • STUN or TURN URI 的值为: turn:stun.xxx.cn
  • 用户名为: aaaaaa
  • 密码为: bbbbbb
测试的结果如下图所示:
ice.png2126×460 64.7 KB
从上图我们可以看到该服务提供了 stun(srflx)和turn(relay)两种服务。
STUN/TURN布署好后,我们就可以使用它进行多媒体数据的传输了,再也不怕因为 NAT 和防火墙的原因导致双方无法通信的问题了。

WebRTC信令控制简介与STUN, TURN服务器搭建的更多相关文章

  1. WebRTC 入门教程(二)| WebRTC信令控制与STUN/TURN服务器搭建

    WebRTC 入门教程(二)| WebRTC信令控制与STUN/TURN服务器搭建 四月 4, 2019 作者:李超,音视频技术专家.本文首发于 RTC 开发者社区,欢迎在社区留言与作者交流. htt ...

  2. STUN/TURN服务器搭建

    目录 STUN/TURN服务器搭建 编译安装 配置使用 添加用户 启动server 测试 开机启动 参考 STUN/TURN服务器搭建 编译安装 编译安装 OpenSSL: sudo apt-get ...

  3. (转)WebRTC信令控制与STUN/TURN服务器搭建

    转:https://rtcdeveloper.com/t/topic/13742 本文将向大家介绍两个方面的知识: WebRTC信令控制 STUN/TURN服务器的搭建 在前面的文章中已经向大家介绍了 ...

  4. webrtc笔记(1): 基于coturn项目的stun/turn服务器搭建

    webrtc是google推出的基于浏览器的实时语音-视频通讯架构.其典型的应用场景为:浏览器之间端到端(p2p)实时视频对话,但由于网络环境的复杂性(比如:路由器/交换机/防火墙等),浏览器与浏览器 ...

  5. stun/turn服务器部署

    目录: 一.简介 二.安装 三.配置与运行 四.运行检测 五.答疑环节 一.简介 本文通过在服务器上安装coturn这个软件,实现搭建STUN服务器和TURN服务器. coturn 简介:是一个免费的 ...

  6. 真实场景中WebRTC 用到的服务 STUN, TURN 和 signaling

    FQ收录转自:WebRTC in the real world: STUN, TURN and signaling WebRTC enables peer to peer communication. ...

  7. (译)WebRTC实战: STUN, TURN, Signaling

    http://xiaol.me/2014/08/24/webrtc-stun-turn-signaling/ 原文:WebRTC in the real world: STUN, TURN and s ...

  8. STUN, TURN, ICE介绍

    STUN STUN协议为终端提供一种方式能够获知自己经过NAT映射后的地址,从而替代位于应用层中的私网地址,达到NAT穿透的目的.STUN协议是典型的Client-Server协议,各种具体应用通过嵌 ...

  9. [转]webrtc学习: 部署stun和turn服务器

    [转]webrtc学习: 部署stun和turn服务器 http://www.cnblogs.com/lingdhox/p/4209659.html webrtc的P2P穿透部分是由libjingle ...

随机推荐

  1. 如何通过<include/>标签重用Mybatis的代码段

    1.首先定义一个sql标签,一定要定义唯一id<sql id="Base_Column_List" >name,age</sql>2.然后通过id引用< ...

  2. 利用SQL为Code128码添加起始符和休止符

    在利用code128码字体打印条码是,打印出来的条形码,扫描枪会出现认不出的情况,这种情况是由于直接将文本设置为code128字体而没有给他们指定起始符和休止符引起的. 经过查资料获发现好多人遇到这样 ...

  3. angularJS常用的内置方法

    angular.lowercase(aaa); angular.uppercase(bbb); angular.isString(); angular.isNumber(); angular.isAr ...

  4. 安装 Keepalived

    安装环境 [root@node1 ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@node1 ~]# cat /proc/v ...

  5. centos6.9 忘记密码解决方法

    若果忘记了 root 的密码,解决方法如下: 我采用的 linux 版本是 centos-6.9 , 经过亲身实践证明,该方法是 ok 的 在开机启动的时候按键盘上的“E”键会进入如下界面. 选择相应 ...

  6. 大数据实践:ODI 和 Twitter (二)

    大数据实践:ODI和Twitter(二) 在前面的文章中,我们已经使用flume将数据从twitter抓取到Hive中,现在我们来看看ODI(Oracle Data Integrator)如何在HIV ...

  7. 使用 IntraWeb (36) - TIWServerControllerBase

    每个应用须有且只有一个 Server Controller. TIWServerControllerBase 所在单元及继承链: IWServerControllerBase.TIWServerCon ...

  8. java程序中实现打开 某个指定浏览器

    package com.test; import java.lang.reflect.Method; //实现打开浏览器并跳到指定网址的类 public class BareBonesBrowserL ...

  9. C++11 多线程编程 使用lambda创建std::thread (生产/消费者模式)

    要写个tcp server / client的博客,想着先写个c++11多线程程序.方便后面写博客使用. 目前c++11中写多线程已经很方便了,不用再像之前的pthread_create,c++11中 ...

  10. StackExchange.Redis 管道 批量 高性能插入数据

    现在用redis来做数据缓存的越来越多了,很多项目都有初始化redis数据的过程,由于初始化的数据比较大,那么该过程越快越好.这里我们以HashSet方法为例, 这里我们推荐用HashEntry[] ...