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

简介:

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

 

 

 

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

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

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

为什么我们需要另外一个数据通道

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

RTCDataChannel则是一个完全不同的途径:
* 它通过RTCPeerConnection API,可以建立点对点互联。由于不需要中介服务器,中间的“跳数”减少,延迟更低。
* RTCDataChannel使用Stream Control Transmission Protocol(SCTP)协议,允许我们配置传递语义:我们可以配置包传输的顺序并提供重传时的一些配置。

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

一个警告:信令、STUN和TURN

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

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

功能

RTCDataChannel API支持灵活的数据类型。它的API是模仿WebSocket设计的,并且支持JavaScript中的二进制类型如Blob、ArrayBuffer和ArrayBufferView,另外还支持字符串。这些类型对于文件传输和多玩家的游戏来说意义重大。


以上来自Ilya GrigorikHigh Performance Browser Networking

RTCDataChannel在不可靠模式(类似于UDP)或可靠模式(类似于TCP)下都能够正常工作。但这两种模式有一些不同:
* 可靠模式:保证消息传输一定成功,并保证按序到达。这自然需要一定量的开销,速度也更慢
* 不可靠模式:不保证消息传输一定成功,也不保证按序到达。这消除了那些开销,速度也更快

在不会丢包的情况下,这两种模式的效率差不多。然而,可靠模式下,丢包将造成后续的所有包阻塞,丢失的数据包也将重传直至其成功到达。当然,我们能在同一个应用中使用多个数据通道,每一个有他们自己的可靠性

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

配置数据通道

网上已经有很多RTCDataChannel的例子了:
simpl.info/dc
googlechrome.github.io/webrtc/dc1.html(SCTP或者RTP)
pubnub.github.io/webrtc(两个PubNub用户)

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

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

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来作区分,并提供一系列的配置选项:

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

我们可以加入一个maxRetransimits选项(最大重传次数),但maxRetransimitTimemaxRetransimits只能设定一个,不能两个懂事设定。如果想使用UDP的方式,设定maxRetransmits为0,orderedfalse。如果想要获取更多信息,请查看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标签提供下载了:

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所带来的优势能够改变你在浏览器中传输数据的观念。

更多资讯

 
 
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。




    本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/7242897.html ,如需转载请自行联系原作者


相关文章
|
30天前
|
JSON 前端开发 Java
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
文章介绍了Java后端如何使用Spring Boot框架响应不同格式的数据给前端,包括返回静态页面、数据、HTML代码片段、JSON对象、设置状态码和响应的Header。
111 1
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
|
10天前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
10天前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
23天前
|
JavaScript 前端开发 Python
django接收前端vue传输的formData图片数据
django接收前端vue传输的formData图片数据
23 4
|
25天前
|
前端开发 JavaScript 编译器
不走弯路,纯前端如何把图片导出成视频!
【10月更文挑战第3天】不走弯路,纯前端如何把图片导出成视频!
38 3
|
10天前
|
NoSQL 前端开发 MongoDB
前端的全栈之路Meteor篇(三):运行在浏览器端的NoSQL数据库副本-MiniMongo介绍及其前后端数据实时同步示例
MiniMongo 是 Meteor 框架中的客户端数据库组件,模拟了 MongoDB 的核心功能,允许前端开发者使用类似 MongoDB 的 API 进行数据操作。通过 Meteor 的数据同步机制,MiniMongo 与服务器端的 MongoDB 实现实时数据同步,确保数据一致性,支持发布/订阅模型和响应式数据源,适用于实时聊天、项目管理和协作工具等应用场景。
|
17天前
|
存储 前端开发 API
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
67 0
|
23天前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
3月前
|
前端开发 JavaScript
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
这篇文章介绍了使用AJAX技术将前端页面中表单接收的多个参数快速便捷地传输到后端servlet的方法,并通过示例代码展示了前端JavaScript中的AJAX调用和后端servlet的接收处理。
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
|
3月前
|
前端开发
第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)