WebRTC搭建前端视频聊天室——数据通道篇

本文翻译自WebRTC data channelsjavascript

在两个浏览器中,为聊天、游戏、或是文件传输等需求发送信息是十分复杂的。一般状况下,咱们须要创建一台服务器来转发数据,固然规模比较大的状况下,会扩展成多个数据中心。这种状况下很容易出现很高的延迟,同时难以保证数据的私密性。html

这些问题能够经过WebRTC提供的RTCDataChannel API来解决,他能直接在点对点之间传输数据。这篇文章将介绍如何建立并使用数据通道,并提供了一些网络上常见的用例html5

为了充分理解这篇文章,你可能须要去了解一些RTCPeerConnection API的相关知识,以及STUN,TURN、信道如何工做。强烈推荐Getting Started With WebRTC这篇文章java


为何咱们须要另一个数据通道

咱们已经有WebSocketAJAX服务器发送事件了,为何咱们须要另一个通讯信道?WebSocket是全双工的,但这些技术的设计都是让浏览器与服务器之间进行通讯。git

RTCDataChannel则是一个彻底不一样的途径:github

  • 它经过RTCPeerConnection API,能够创建点对点互联。因为不须要中介服务器,中间的“跳数”减小,延迟更低。
  • RTCDataChannel使用Stream Control Transmission Protocol(SCTP)协议,容许咱们配置传递语义:咱们能够配置包传输的顺序并提供重传时的一些配置。

基于SCTP的支持的RTCDataChannel已经可以在桌面的Chrome、Opera和Firefox中使用,移动端则有Android支持。web


一个警告:信令、STUN和TURN

尽管WebRTC容许点对点的通讯,但它依然须要服务器:
* 信令传输:创建点对点的链接须要传输一些媒体和网络相关的元数据信息,须要经过服务器
* NAT和防火墙穿透:咱们须要经过ICE框架来创建点与点之间的网络路径。可使用STUN服务器(肯定双方的可公开访问你的IP地址和端口)以及TURN服务器(若是直接链接失败,就必须数据中继了)chrome

WebRTC in the real world: STUN, TURN, and signaling 文章详细介绍了WebRTC如何与这两种服务器进行交互api


功能

RTCDataChannel API支持灵活的数据类型。它的API是模仿WebSocket设计的,而且支持JavaScript中的二进制类型如Blob、ArrayBuffer和ArrayBufferView,另外还支持字符串。这些类型对于文件传输和多玩家的游戏来讲意义重大。
这里写图片描述
以上来自Ilya GrigorikHigh Performance Browser Networking浏览器

RTCDataChannel在不可靠模式(相似于UDP)或可靠模式(相似于TCP)下都可以正常工做。但这两种模式有一些不一样:

  • 可靠模式:保证消息传输必定成功,并保证按序到达。这天然须要必定量的开销,速度也更慢
  • 不可靠模式:不保证消息传输必定成功,也不保证按序到达。这消除了那些开销,速度也更快

在不会丢包的状况下,这两种模式的效率差很少。然而,可靠模式下,丢包将形成后续的全部包阻塞,丢失的数据包也将重传直至其成功到达。固然,咱们能在同一个应用中使用多个数据通道,每个有他们本身的可靠性

下面将说明如何去配置可靠模式或不可靠模式的RTCDataChannel

配置数据通道

网上已经有不少RTCDataChannel的例子了:

ps:PubBub是一个实时信息通信应用开发公司

在这个例子中,浏览器建立了一个对等链接链接到本身。而后在这个对等链接n上建立了一个数据通道,发送了一些消息。最后,消息成功抵达并显示在页面上。

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
var peerConnection = new RTCPeerConnection(); //使用信令传输信道建立对等链接 var dataChannel = peerConnection.createDataChannel("myLabel", dataChannelOptions); dataChannel.onerror = function (error) { console.log("Data Channel Error:", error); }; dataChannel.onmessage = function (event) { console.log("Got Data Channel Message:", event.data); }; dataChannel.onopen = function () { dataChannel.send("Hello World!"); }; dataChannel.onclose = function () { console.log("The Data Channel is Closed"); };

dataChannel对象创建在一个已经建立完毕的对等链接之上。它能够建立在信令传输先后。另外,能够赋予一个label来做区分,并提供一系列的配置选项:

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
var dataChannelOptions = { ordered: false, //不保证到达顺序 maxRetransmitTime: 3000, //最大重传时间 };

咱们能够加入一个maxRetransimits选项(最大重传次数),但maxRetransimitTime或maxRetransimits只能设定一个,不能两个懂事设定。若是想使用UDP的方式,设定maxRetransmits为0,ordered为false。若是想要获取更多信息,请查看RFC 4960(SCTP)和RFC 3758(SCTP部分可靠性)

  • ordered: 数据通道是否保证按序传输数据
  • maxRetrasmitTime:在信息失败前的最大重传时间(强迫进入不可靠模式)
  • maxRetransmits:在信息失败前的最大重传次数(强迫进入不可靠模式)
  • protocol:容许使用一个自协议,但若是协议不支持,将会失败
  • negotiated:若是设为true,将一处对方的数据通道的自动设置,也就是说,将使用相同的id以本身配置的方式与对方创建数据通道
  • id:为数据通道提供一个本身定义的ID

它安全吗?

在WebRTC全部的组件中,都会强制进行加密。在RTCDataChannel中,全部的数据都使用数据报传输层安全性(DTLS)。DTLS是SSL的衍生,也就是说,你的数据将和使用基于SSL的链接同样安全。DTLS已经被标准化,并内置于全部支持WebRTC的浏览器中。若是须要更多关于DTLS信息,请访问Wireshark的维基

改变你考虑数据的方式

处理大批量的数据,一直是JavaScript的一个难点。正如Sharefest所提出的观点,咱们须要用一种新的方式来考虑数据。若是你须要传输一个比你当前可用内存更大的文件,就必须考虑新的保存信息的方式了。这也就是像FileSystem API等技术存在的意义。咱们将在下面进行介绍

搭建一个文件共享应用

如今咱们能够经过RTCDataChannel来建立文件共享应用。将应用创建在RTCDataChannel智商也意味着传输的文件数据都将加密,并且不会通过应用的服务器端。经过这个功能,咱们可以实现多用户之间的互联,进行文件共享。

须要成功传输一个文件,咱们须要以下几步:
1. 经过JavaScript的File API读取文件数据
2. 使用RTCPeerConnection在用户间建立一个对等链接
3. 使用RTCDataChannel在用户间建立一个数据通道

在使用RTCDataChannel时,还有一些其余问题须要考虑:

  • 文件大小:若是文件很小,可以直接经过一个Blob进行存储和读取,那么咱们能够直接使用File API将其读进内存,并经过可靠的数据通道发送(可是须要注意的是,浏览器有最大传输大小的限制)。随着文件变大的话,就不那么简单了。咱们须要一个分块机制:文件将分红多个碎片,称为文件块。咱们再也不直接发送整个文件,而是一次发送一个文件块。固然文件块上会有一些元数据如块的ID,方便对方可以识别。接收到文件块以后,首先将这些文件块保存在离线存储中(例如,使用FileSystem API),只有当全部块都接收完毕,才将其拼合起来成为完整的文件,保存到用户的硬盘。
  • 速度:文件传输更适合使用可靠模式(像TCP)仍是非可靠模式(像UDP)还有待商榷。若是应用知识简单的一对一文件传输,使用不可靠的数据通道将须要设计必定的响应/重传协议。你必须本身来实现它,就算你很是优秀,它仍然不会比使用可靠的数据传输快多少。可靠而无序的数据通道将会更加合适,可是若是是多方文件传输,结果可能会有所不一样。
  • 块大小:这些是你的应用中的最小的“原子”数据。目前有传输大小限制(尽管之后可能不会有限制),因此必需要进行分块。目前建议的最大块大小为16KB。

若是文件已经被彻底传输,就可使用一个a标签提供下载了:

 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
function saveFile(blob) { var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = 'File Name'; link.click(); };

目前已经有两个文件共享的应用使用了这种方式:pubnub.github.io/rtc-pubnub-filesharegithub.com/Peer5/ShareFest,这两个应用都是开源的,并提供了基于RTCDataChannel的文件共享

那么咱们能作什么?

RTCDataChannel为文件共享、多人游戏以及内容交付应用提供了全新的实现思路:
* 上面已经提到了点对点的文件传输了
* 多人游戏,与诸如WebGL等其余技术相结合,好比Mozilla的Banana Bread
* 内容交付:由PeerCDN从新改造的一个用于提供点对点通讯提供资源的框架

改变你构建应用的方式

如今咱们可以使用高新能、低延迟的RTCDataChannel来建立更优秀的应用了。一些框架,诸如PeerJSPubNub WebRTC SDK,使得RTCDataChannel更加易于使用,其API也被各个平台所支持

RTCDataChannel所带来的优点可以改变你在浏览器中传输数据的观念。


更多资讯

相关文章
相关标签/搜索