资讯专栏INFORMATION COLUMN

WebRTC 初探

williamwen1986 / 839人阅读

摘要:虽然是点对点通信,但还是需要服务器来初始化连接,并传递一些信息。服务器实现点对点通信的关键在于两个浏览器之间能直接发送和接收数据包,但一般情况下,浏览器或手机都是通过路由器访问,所以存在网络地址转换。

WebRTC

浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转。比如现在有两个客户端,甲和乙,他们俩想要通信,首先需要甲和服务器、乙和服务器之间建立信道。甲给乙发送消息时,甲先将消息发送到服务器上,服务器对甲的消息进行中转,发送到乙处,反过来也是一样。这样甲与乙之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽。同时这样的信道并不适合数据流的传输,如何建立浏览器之间的点对点传输,一直困扰着开发者。

WebRTC 是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的 JavaScript 接口。WebRTC 不仅可传输视频,也可以传输其他数据例如文本、图片等。需要注意的是,WebRTC 并不是浏览器的一个子集,浏览器只是根据 WebRTC 的标准协议实现了 WebRTC 的原生接口。Android 和 IOS 系统也支持 WebRTC 。

WebRTC 应用包括下面四个主要的概念:

信令服务器(Signalling servers)

ICE 服务器(ICE servers)

媒体服务器 (Media servers)

JavaScript 接口 (JavaScript API)

信令服务器

信令服务器主要用于在两个用户之间交换信息。虽然 WebRTC 是点对点通信,但还是需要服务器来初始化连接,并传递一些信息。
WebRTC 没有定义用于建立信道的信令的协议,因此可以使用任意的传输方式,例如 WebSocket, XMPP, SIP, AJAX。

你可以使用实时的传输协议比如 WebSocket 来交换数据,也可以使用简单的 GET/POST 方式轮询服务器来获取数据。

信令服务器传送的数据有:

协商媒体功能和设置

标识和验证会话参与者的身份

控制媒体会话、指示进度、更改会话和终止会话

其中只有第一项的必备功能。其他都可以根据业务需求自由调整。

媒体协商最重要的功能在于,为参与点对点通信的两个浏览器之间交换会话描述协议(SDP)。SDP 包含浏览器的 RTP 媒体栈配置所需的全部信息,包括媒体类型(音频、视频、数据)、所需的编解码器,用于编解码器的哥哥参数或设置,以及有关带宽的信息。此外,信令通道还用于交换候选地址,以便进行 ICE 打洞。

ICE 服务器

实现点对点通信的关键在于两个浏览器之间能直接发送和接收数据包,但一般情况下,浏览器或手机都是通过路由器访问 Internet,所以存在网络地址转换(NAT)。位于 NAT 之内的 IP 地址是私有地址,外部无法访问。分配给 NAT 的 IP 地址才是公共地址。NAT 每次从内部到外部转发数据包时都使用公共地址。

交互式建立连接(ICE)是一种标准穿透协议,它利用 STUN 和 TURN 服务器来建立连接。

STUN 服务器可以遍历 NAT,获取浏览器的候选地址,包括私有地址、外层 NAT 的公共 IP 地址等。通信信令通道可以交换候选地址,浏览器一旦发送并收到了候选项,就会开始进行连接检查,若检查成功,便使用该候选项发送媒体。

在大多情况下,通过穿透可以建立直接对等连接。但是,若 NAT 或防火墙限制非常严格,无法建立连接,就只能通过 TURN 服务器中继媒体。

媒体服务器

媒体服务器不是必须的,但在多方会话或需要对媒体做额外处理的情况下可以考虑加入。对于有多个浏览器参与的会议,可以采用一个集中式媒体服务器。在这种情况下,美国浏览器都只需与媒体服务器建立单个连接即可,这种结构的优势是额能够扩展非常大的会话,同时可以在最大限度上减少当有新加入者加入会话事美国浏览器所需的处理工作量。同时,媒体服务器也可对媒体进行分析、处理、保存等工作。

JavaScript 接口 getUserMedia

通过调用 navigator.getUserMedia() 可以获取视频或音频的数据,constraints 参数可以选择是否获取视频音频。下面是一个简单的示例

var constraints = {
  audio: false,
  video: true
};
var video = document.querySelector("video");

function successCallback(stream) {

  if (window.URL) {
    video.src = window.URL.createObjectURL(stream);
  } else {
    video.src = stream;
  }
}

function errorCallback(error) {
  console.log("navigator.getUserMedia error: ", error);
}

navigator.getUserMedia(constraints, successCallback, errorCallback);
RTCPeerConnection

RTCPeerConnection 是 WebRTC 中最重要的一个接口,用于确定 ICE 服务器、交换 SDP。连接过程如下:

创建 RTCPeerConnection 对象

RTCPeerConnection 的参数用于确定 ICE 服务器,下面是使用了 google 开放的 STUN 服务器

let iceServer = {
    "iceServers": [{
        "url": "stun:stun.l.google.com:19302"
    }]
};
let pc = new RTCPeerConnection(servers);

将媒体流放入 RTCPeerConnection 对象中

pc.addStream(localStream);

通过 offer 和 answer 交换 SDP 描述符

甲和乙各自建立一个PC实例

甲通过 PC 所提供的 createOffer() 方法建立一个包含甲的 SDP 描述符的 offer 信令

甲通过 PC 所提供的 setLocalDescription() 方法,将甲的SDP描述符交给甲的 PC 实例

甲将 offer 信令通过服务器发送给乙

乙将甲的 offer 信令中所包含的的SDP描述符提取出来,通过PC所提供的 setRemoteDescription() 方法交给乙的PC实例

乙通过PC所提供的 createAnswer() 方法建立一个包含乙的 SDP 描述符 answer 信令

乙通过PC所提供的 setLocalDescription() 方法,将乙的 SDP 描述符交给乙的PC实例

乙将answer信令通过服务器发送给甲

甲接收到乙的answer信令后,将其中乙的SDP描述符提取出来,调用setRemoteDescripttion()方法交给甲自己的PC实例

ICE 打洞

当网络候选可用时,通过信令服务器将其发送到对方浏览器

pc.onicecandidate = function(event) {
  if (event.candidate) {
    sendToServer(event.candidate)
  }
};

当接受到对方网络候选时,将其加入

let candidate = new RTCIceCandidate(candidate);
pc.addIceCandidate(candidate);

监听对方发送的媒体是否可用,并播放媒体

pc.onaddstream = event => {
  remoteVideo.src = window.URL.createObjectURL(event.stream);
}
RTCDataChannel

RTCDataChannel 是 RTCPeerConnection API 的一部分,只有在创建了 RTCPeerConnection 实例后才能创建数据通道。数据通道可以用于发送文本或是文件。

pc = new RTCPeerConnection();
dc =  pc.createDataChannel("dc");

dc.onmessage = event => console.log(event.data);

dc.send("text");
dc.sed(new arraybuffer(32))

在另一端可以使用 ondatachannel 获得 RTCDataChannel 对象

pc.ondatachannel = event => dc = event.channel;
参考资料

https://codelabs.developers.g...

https://webrtc.org/

https://segmentfault.com/a/11...

http://www.muazkhan.com/2013/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83486.html

相关文章

  • webRTC 初探

    摘要:如果要多人会话,就要单对单建立多个连接。同样的步骤执行多次就可以了客户端代码开始结束发送打开页面即开启等待模式服务端代码 webRTC介绍 webRTC是英文Web Real-Time Communication的缩写,中文翻译网页实时通信,是浏览器不需要服务器的中转,可以直接通信的技术 webRTC 应用 网上的很多教程都会包含实时视频的介绍,不过我感觉视频看起来很酷,不过却不是we...

    klinson 评论0 收藏0
  • Hola~ 一款基于Electron的聊天软件

    摘要:前言本项目旨在从零到壹,制作一款界面精美的聊天软件。因为本人是开发,设计功底欠缺,所以软件设计的有点丑,如果有大神有更好的,欢迎。 Hola 前言 本项目旨在从零到壹,制作一款界面精美的聊天软件。 Github 地址因为已工作,所以可能没有多少时间来继续跟进这个项目了,项目可优化的点已在下文列出,欢迎大家 Fork 或 Star。 ps: 征 logo 一枚。因为本人是开发,设计功底...

    Kaede 评论0 收藏0
  • WebRTC入门教程(三) | Android 端如何使用 WebRTC

    摘要:下面我们就看一下具体如何申请权限静态权限申请在项目中的中增加以下代码动态权限申请随着的发展,对安全性要求越来越高。其定义如下通过上面的代码我们就将显示视频的定义好了。当发送消息,并收到服务端的后,其状态变为。 作者:李超,如遇到相关问题,可以点击这里与作者直接交流。 前言 在学习 WebRTC 的过程中,学习的一个基本步骤是先通过 JS 学习 WebRTC的整体流程,在熟悉了整体流程之后,...

    番茄西红柿 评论0 收藏0
  • WebRTC入门教程(三) | Android 端如何使用 WebRTC

    摘要:下面我们就看一下具体如何申请权限静态权限申请在项目中的中增加以下代码动态权限申请随着的发展,对安全性要求越来越高。其定义如下通过上面的代码我们就将显示视频的定义好了。当发送消息,并收到服务端的后,其状态变为。 作者:李超,如遇到相关问题,可以点击这里与作者直接交流。 前言 在学习 WebRTC 的过程中,学习的一个基本步骤是先通过 JS 学习 WebRTC的整体流程,在熟悉了整体流程之后,...

    jsbintask 评论0 收藏0
  • WebRTC 及点对点网络通信机制

    摘要:本质上允许网页程序创建点对点通信,我们将会在随后的章节中进行介绍。信令涉及网络检索和穿透,会话创建及管理,通信安全,媒体功能元数据和调制及错误处理。这样就会完全建立及激活节点间的网络套接字会话。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 这是 JavaScript 工作原理第十八章。 概述 何为 WebRTC ?首先,字面上已经...

    Rango 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<