编程技术记录

世界你好!

webrtc介绍

详细请访问

简介

WebRTC(网页实时通信技术),是一系列为了建立端到端文本或者随机数据的规范,标准,API和概念的统称。

任何实现了WebRTC标准的软件之间均可通信,如PC浏览器–手机浏览器、浏览器–App、App–App。通信双方是对等的,但通常还要引入服务端,以便于对等端能够找到对方。

移动端浏览器对WebRTC的支持

  • Android 4.4以上

  • iOS 11以上

     

WebRTC应用不需要非常高性能就能够平稳运行、拥有良好体验。对于WebRTC来说,获取特定硬件的权限也不是必需的。Web应用和原生应用对比:

  • 原生应用会比Web应用更快,拥有更高级别的硬件权限;混合应用的运行速度更慢,不能使用移动设备的全部权限。
  • 原生应用在不同的平台上的代码复用度有待提高;混合应用开发起来会更快,更省钱

结论:如果高性能和极致体验不是软件的必不可少的要求,那么,在绝大多数情况下,用户根本注意不到原生和混合WebRTC应用之间的差别。

实现基本的数据通道

对浏览器而言,WebRTC API处于底层且十分复杂。不过我们可以使用封装好的高级别的API—-simple-peer是一个基础的,非常洁净的低层P2P连接封装器.下面的示例是simple-peer的一个标准例子。

演示步骤:

  • 1、创建index.html文件,文件内容为上面的代码
  • 2、下载simplepeer.min.js,放到和index.html同目录下
  • 3、用浏览器打开file:///本地路径目录/index.html#1(这里使用file协议,是因为没有部署index.html到服务端),可以看到网页中输出了一个offer邀请信令,格式类似下面例子
  • 4、用另外一个浏览器打开file:///本地路径目录/index.html,注意没有#1,然后将步骤3中的offer信令复制到本步骤中网页的提交框中,并提交,然后可以在网页中看到一answer应答信令,格式类似下面例子
  • 5、将步骤4中的answer信令制到步骤3中网页的提交框中,并提交。打开浏览器的开发者模式,可以看到两个浏览器已经建立了数据通道,并互相发送了一个随机数消息

文件传输

建立起基本的数据通道后,就可以做一些比较直观的不那么抽象事情了,比如传输文件。对于使用WebRTC进行文件传输,有一些细节需要处理

修改传输速度限制

Chrome默认将WebRTC的数据通道传输速度限制在30K,我们可以修改SDP的内容来提高上限,例如256K。

选择并读取文件数据

我们选取基本的input控件作为文件选择器,并监听文件选择动作。

考虑到传输速度限制,在读取文件内容时,应进行切片–循环读取、发送,直到文件末尾。

自动下载文件

接收完成后,数据还保存在浏览器内存(缓存)中,需要触发文件下载机制将数据下载到本地。

完整代码

演示步骤:

  • 1、创建index.html文件,文件内容为上面的代码
  • 2、下载simplepeer.min.js,放到和index.html同目录下
  • 3、用浏览器打开file:///本地路径目录/index.html#1(这里使用file协议,是因为没有部署index.html到服务端),可以看到网页中输出了一个offer邀请信令。
  • 4、用另外一个浏览器打开file:///本地路径目录/index.html,注意没有#1,然后将步骤3中的offer信令复制到本步骤中网页的提交框中,并提交,然后可以在网页中看到一answer应答信令。
  • 5、将步骤4中的answer信令制到步骤3中网页的提交框中,并提交。打开浏览器的开发者模式,可以看到两个浏览器已经建立了数据通道,此时可以传输文件了。

音视频通话

还是使用simple-peer,利用浏览器的媒体能力,搭建一个简单的局域网内音视频通话模型。

https

一般情况下,在线网页使用浏览器的摄像头和麦克风能力时,浏览器的要求是使用htpps。这里,我们使用python简单的搭建一个https服务器

首先,用openssl自签名一个RSA证书(如果有机构颁发的证书,则可以忽略此步骤)

上述命令会要求输入初始密码,可以输入简单的密码如123456(仅测试用),同时输出两个文件key.pemcert.pem,记住两个文件的路径。

参考Simple Python HTTP(S) Server — Example,创建https_server.py文件,内容如下

key.pemcert.pem放在和https_server.py同目录下,然后运行命令并输入证书密码(本例为123456)

一个简单的https服务搭建完毕

访问音视频流

我们可以使用navigator.mediaDevices.getUserMedia来获取音视频流数据

获取到媒体流后,可以将媒体数据展示在video标签上,这样更加直观。 需要注意的是,对于iOS设备,建议使用iOS11以后的版本,且需要添加playsinline webkit-playsinline="true"以解决video标签的黑屏/白屏问题。

完整代码

演示步骤:

  • 1、创建index.html文件,文件内容为上面的代码,放在https_server.py同目录下
  • 2、下载simplepeer.min.js,放到和index.html同目录下
  • 3、运行 python https_server.py
  • 4、用浏览器打开https://ip地址:4443/index.html#1,可以看到网页中输出了一个offer邀请信令。
  • 5、用局域网内的另外一个终端浏览器打开https://ip地址:4443/index.html,注意没有#1,然后将步骤4中的offer信令复制到本步骤中网页的提交框中,并提交,然后可以在网页中看到一answer应答信令。
  • 6、将步骤4中的answer信令制到步骤3中网页的提交框中,并提交。顺利的话,可以两个浏览器可以显示到对方的媒体流

屏幕共享

屏幕共享的原理和音视频通话的原理类似,唯一不同的是媒体流的数据来源不一样,因此,我们可以在音视频通话的基础上,修改一个屏幕共享的实现。

Safari浏览器对MediaStream支持不够友好,建议使用两个Chrome浏览器测试。

捕捉屏幕

Chrome浏览器在2018年后才开始支持navigator.mediaDevices.getDisplayMedia

完整代码

演示步骤和音视频通话的例子基本一样。

 

NAT穿透之STUN/TURN

NAT(Network Address Translation,网络地址转换),典型的应用场景是公网IP地址和私有IP地址转换,通过使用少量的公网IP地址来代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。

NAT分为四种类型,Full Cone(完全锥形)、Restricted Cone(限制锥形)、Port Restricted Cone(端口限制锥形)和Symmetric(对称形)。

为了能让两个处在不同NAT网络的WebRTC终端能够进行数据、媒体通信,需要借助STUN/TURN来实现NAT穿透。

一般来说,STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators), NAT的UDP的简单穿越,是一种网络协议,通过暴露两个WebRTC终端在公网上的地址,可以在锥形NAT(完全锥形、限制锥形、端口限制锥形)进行穿透,从而实现P2P通信。

TURN(Traversal Using Relays around NAT),也是一种网络协议,可以解决STUN不能穿透对称形NAT的问题。和STUN不同的是,TURN实现穿透的方法是中转。

如果在公网上架设了STUN/TURN服务器,那么处在不同NAT网络的WebRTC终端进行通信就变得比较容易了。在初始化WebRTC终端时,可以配置STUN/TURN服务地址列表:

使用STUN/TURN后,可以较为方便的实现NAT穿透。当然,STUN/TURN不是必需的,但是强烈推荐使用。

信令服务器

为何还需要引入信令服务器?先回顾下本文上面的例子,使用simple-peer创建WebRTC终端,生成SDP信令(如offeranswer),那么他们如何交换信令呢?本文上文的例子是通过手动复制粘贴实现的,而真实的业务场景中,这个人工操作是由信令服务器完成的。

WebRTC并没有规定信令服务使用哪种协议实现,所以本文采用最简单的实现方式(真实业务场景不会使用),HTTP + GET + POST实现。 先来熟悉下引入信令服务器后,两个WebRTC终端建立连接的过程:

  • 1、A端 初始化offer信令.
  • 2、A端 向STUN/TURN查询自己的公网地址,STUN/TURN会返回candidate列表A(可连接的候选地址列表).
  • 3、A端 将offer信令和candidate列表A一同发给信令务器,由信令服务器转发给 B端.
  • 4、B端 收到offer信令和candidate列表A, 从candidate列表A选择合适的地址发送NAT穿透报文, 同时向STUN/TURN查询自己的公网地址获取candidate列表B.
  • 5、B端 生成answer信令,并将answer信令和candidate列表B发送给信令服务器,由信令服务器转发给 A端.
  • 6、A端 收到answer信令和candidate列表B,从candidate列表B选择合适的地址发送NAT穿透报文.
  • 7、A、B建立连接。

以上只是基本的连接建立过程,当然真实业务场景会比较复杂,如可能有媒体协商。真实的业务场景下,连接过程依然可以从上面的基本过程演变出来。

信令服务实现

上面说到本文使用HTTP + GET + POST实现,客户端使用POST负责发送信令,通过GET轮询获取信令。 依然适用Python实现。

完整代码

演示步骤:

  • 1、创建index.html文件,文件内容为上面的代码
  • 2、下载simplepeer.min.js,放到和index.html同目录下
  • 3、用浏览器打开https://公网地址/index.html#1
  • 4、用另外一个浏览器打开https:///公网地址/index.html,注意没有#1
  • 5、正常情况下,应能建立连接。

© Beli. All Rights Reserved.