自护意识

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WebRTC

简介

WebRTC(Web Real-Time Communications), 是一个可以让我们在浏览器上实现P2P的协议。 我们可以使用此协议传输文字,语音,视频及文件等内容。 本文将我学习过程中的一些个人理解记录下来了。强烈建议阅读MDN的文档进行系统学习。

简单流程

首先,我们有点A和点B想要互相通信。同时,我们需要一个中间人S用来传输信息,S可以是一个服务器,也可是是一个人来手动传递。

流程

  1. A和B分别创建RTCPeerConnection对象 - connection.

  2. A和B分别监听各自 connection.onicecandidate 事件,此事件被调用时会提供一个唯一凭证candidate.

  3. A首先调用connection.createOffer获得一个凭证offer, 然后调用connection.setLocalDescription(offer).之后通过S把offer传递给B.

  4. B收到A提供的offer, 调用connection.setRemoteDescription(offer),然后通过connection.createAnswer()得到一个凭证answer,调用connection.setLocalDescription(answer),并通过S将answer返回给A.

  5. A收到B提供的answer, 调用connection.setRemoteDescription(answer).

  6. 此时A和B都获取到了本地和远程的基本信息.

  7. 之后A和B再通过类似流程相互传递拿到的candidate, 分别调用 connection.addIceCAndidate(candidate).注意此时传入的candidate是对方提供的.

  8. 以上步骤完成后, A和B之间就建立好了P2P的链接,可以进行通信了.

    一些说明

  9. RTCPeerConnection的createOffer和createAnswer方法创建的都是SDP对象,在浏览器中为RTCSessionDescription类.

  10. SDP对象用来描述需要传输内容的一些信息,例如格式,分辨率,编码。因此在调用createOffer和createAnswer前需要先调用传输内容相关的接口,如addStream.

  11. 双方交换SDP,即可让双方知道对方要传输内容的一些基本信息。

  12. A和B建立链接则需要分别拿到对方的candidate.

    如何获取视频和音频流

    以上流程只提供了如何使A和B建立链接,那么要如何传输视频流呢?

navigator.mediaDevices.getUserMedia({ video: true, audio: false })
    .then(stream => {
        // 使用 stream
    }).catch(err => {
        console.log('An error occured ' + err);
    });
  • 创建connection之后监听 connection.onaddstream 事件.
  • A在createOffer前, B在createAnswer前调用connection.addStream()方法,传入第一步获得的stream. 之所以需要在createOffer和createAnswer之前调用,是因为WebRTC需要根据传输的内容创建关于的信息,例如内容的格式,分辨率.
  • 当A和B的通信建立成功之后,之前监听的onaddstream事件会被调用,此时通过传入的参数拿到对方的stream.

A和B到底如何建立的链接?

一开始学习的时候我一直有疑问,现实生活中网络情况很复杂,如果没有公网ip或者不在一个网段下,WebRTC是如何让A和B互相找到对方,或者说通过哪些配置我才能让A和B互相找到。

其实是WebRTC使用了ICE协议.目前ICE主要有两种协议,分别是STUNTURN.

我们在创建RTCPeerConnection对象时可以传入ICE有关的配置,例如:

const peerConnection = new RTCPeerConnection({
    iceServers: [
        { urls: ['turn:turn1.example.com', 'turn:turn2.example.com'] }
        { urls: 'stun:stun1.example.com' }
    ]
});

然后WebRTC在无法直连时会依次尝试通过提供的iceServers, 直到某一个可以使用,然后调用 RTCPeerConnection.onicecandidate 回调方法,传入可以使用的ICE token. A和B分别拿到自己的ICE token, 通过S传给对放, 当A和B都拿到对方的token后就知道如何建立到对方的链接了。

因此为了可以使A和B方便的建立链接,我们需要提供一个Signal服务器S和数个支持ICE协议的服务器.其中S服务器只要负责在A和B之间传输数据,因此可以自己选择喜欢的方式实现,常用的就是使用WebSock, 类似于实现一个简单的聊天室。而支持ICE协议的服务器,coturn就可以很好的胜任,当然也可以选择自己喜欢的ICE服务器,甚至使用第三方提供的。

一些资料

在学习过程中我主要依靠MDN上提供的资料和教程。
1. 视频通话demo.
1. demo代码.
1. coturn编译中openssl问题的解决方法.

 

posted on 2017-10-10 18:51  自护意识  阅读(1116)  评论(0编辑  收藏  举报