JS的工作原理:WebRTC和P2P通讯


今天,我们将发布一系列有关JavaScript的所有材料的第18部分的译文。 在这里,我们将讨论WebRTC技术,该技术旨在实时组织浏览器应用程序之间的直接数据交换。

图片

复习


什么是WebRTC? 首先,值得一提的是,缩写RTC代表实时通信(Real-Time Communication,实时通信)。 仅此一项就提供了有关此技术的许多信息。

WebRTC在Web平台的机制中占有非常重要的位置。 以前,桌面聊天等应用程序使用的P2P技术(点对点,点对点连接,点对点,点对点网络)为他们提供了Web项目所没有的机会。 WebRTC对网络技术产生了影响。

如果我们笼统地看一下WebRTC,则WebRTC允许Web应用程序创建P2P连接,我们将在下面讨论。 此外,我们将在此处介绍以下主题,以全面展示WebRTC的内部结构:

  • P2P通信。
  • 防火墙和NAT穿越技术。
  • 信令,会话和协议。
  • WebRTC API

P2P通讯


假设有两个用户在各自的浏览器中启动了一个应用程序,该应用程序允许您使用WebRTC组织视频聊天。 他们想建立一个P2P连接。 做出决定后,我们需要一种机制,该机制允许用户的浏览器相互查找并建立通信,同时考虑到系统中可用的信息保护机制。 建立连接后,用户将能够实时交换多媒体信息。

与浏览器的P2P连接相关的主要困难之一是,浏览器必须首先发现彼此,然后基于套接字建立网络连接以确保双向数据传输。 我们建议讨论与安装此类连接相关的困难。

当网络应用程序需要一些数据或资源时,它便从服务器上下载了数据或资源。 服务器地址是应用程序已知的。 例如,如果我们谈论的是创建P2P聊天,其操作基于浏览器的直接连接,那么这些浏览器的地址是事先未知的。 结果,为了建立P2P连接,您将不得不处理一些问题。

防火墙和NAT穿越协议


通常,普通计算机没有分配静态的外部IP地址。 其原因是此类计算机通常位于防火墙和NAT设备之后。

NAT是一种将位于防火墙后面的内部本地IP地址转换为外部全局IP地址的机制。 首先,出于安全原因,使用NAT技术,其次,由于IPv4对可用全局IP地址的数量施加了限制。 这就是使用WebRTC的Web应用程序不应依赖于当前设备具有全局静态IP地址这一事实的原因。

让我们看看NAT是如何工作的。 如果您在公司网络上并连接到WiFi,则会为您的计算机分配一个仅在NAT设备后面存在的IP地址。 假设这是IP地址172.0.23.4。 但是,对于外部世界,您的IP地址可能类似于164.53.27.98。 因此,外部世界将您的请求视为来自地址164.53.27.98,但是由于使用了NAT,计算机对外部服务的请求的答复将发送到您的内部地址172.0.23.4。 使用转换表会发生这种情况。 请注意,除了IP地址外,网络还需要端口号。

鉴于NAT参与了系统与外界的交互过程,因此,为了建立WebRTC连接,浏览器需要知道要与之通信的浏览器所在的计算机的IP地址。

这是STUN(用于NAT的会话遍历实用程序)和TURN(在NAT周围使用中继的遍历)服务器进入现场的地方。 为了确保WebRTC技术的运行,首先要向STUN服务器发出请求,以查找您的外部IP地址。 实际上,我们正在谈论向远程服务器发出的请求,以便找出服务器从哪个IP地址接收此请求。 收到类似请求后,远程服务器将发送一个响应,其中包含对其可见的IP地址。

基于该方案可以运行并且您收到有关外部IP地址和端口的信息这一假设,那么您可以告诉系统中的其他参与者(我们将其称为对等方)如何直接与您联系。 这些对等方也可以使用STUN或TURN服务器执行相同的操作,并可以告诉您为其分配了哪些地址。

信令,会话和协议


如上所述,发现网络信息的过程是大型信令系统的一部分,在WebRTC的情况下,该系统基于JSEP(JavaScript会话建立协议)标准。 信令包括网络资源发现,会话创建和管理,通信安全性,媒体参数的协调,错误处理。

为了使连接正常工作,对等方必须就将交换的数据格式达成一致,并收集有关运行该应用程序的计算机的网络地址的信息。 共享此关键信息的信令机制不是WebRTC API的一部分。

WebRTC标准未定义信令,并且未在其API中实现信令,以便在所使用的技术和协议中提供灵活性。 信号和支持它的服务器是WebRTC应用程序开发人员的责任。

如上所述,基于在浏览器中运行的WebRTC应用程序能够使用STUN确定浏览器的外部IP地址的假设,下一步是讨论会话参数并与另一个浏览器建立连接。

会话参数的初步讨论和连接的建立是使用专门用于多媒体通信的信令/通信协议进行的。 此外,此协议负责遵守管理和终止会话的规则。

这些协议之一被称为SIP(会话发起协议)。 请注意,由于WebRTC信令子系统的灵活性,SIP不是唯一可以使用的信令协议。 此外,所选的信令协议必须与称为SDP(会话描述协议)的应用层协议一起使用,该协议在使用WebRTC时使用。 使用SDP协议传输与多媒体数据有关的所有元数据。

任何试图联系另一个对等方的对等方(即使用WebRTC的应用程序)都会为ICE协议(交互式连接建立)生成一组候选路由。 候选人代表可以使用的IP地址,端口和传输协议的组合。 请注意,一台计算机可以具有许多网络接口(有线,无线等),因此可以为它分配多个IP地址,每个接口分配一个IP地址。

这是带有MDN的示意图,说明了上述数据交换过程。

建立P2P连接所需的数据交换过程

建立连接


如上所述,每个对等方首先找出其外部IP地址。 然后,动态创建信令数据的“通道”,用于检测对等端并支持对等端之间的数据交换,以讨论会话参数及其安装。

这些“通道”是未知的,外界无法访问;访问它们需要唯一的标识符。

请注意,由于WebRTC的灵活性,并且信号处理过程未由标准定义,因此“通道”的概念及其使用顺序可能会因所使用的技术而略有不同。 实际上,某些协议不需要组织数据交换的“通道”机制。 出于本材料的目的,我们假定使用系统实施中的“通道”。

如果两个或多个对等方连接到同一“通道”,则对等方将有机会交换数据并讨论会话信息。 此过程类似于发布者-订阅者模板。 通常,发起连接的对等方使用诸如SIP或SDP的信令协议发送“要约”。 发起者希望从提案的接收者那里收到“响应”,该响应与所考虑的“渠道”相关。

收到答案后,将确定并讨论每个宴席收集的最佳ICE候选人的过程。 选择最佳ICE候选者后,将商定将在对等点与网络路由机制(IP地址和端口)之间交换的数据参数。

然后,在对等体之间建立活动的网络套接字会话。 此外,每个对等方创建本地数据流和数据通道的端点,并且多媒体数据的双向传输开始使用所应用的技术。

如果选择最佳ICE候选者的协商过程不成功(有时由于防火墙和NAT系统的故障而发生),则使用备份选项,其中包括使用TURN服务器作为中继。 此过程涉及充当中介的服务器,该中介中继对等体之间交换的数据。 请注意,此方案不是真正的P2P连接,在该P2P连接中,对等方直接相互传输数据。

当使用使用TURN的后备进行数据交换时,每个对等方不再需要知道如何与他人通信以及如何向其传输数据。 相反,对等方需要知道哪个外部TURN服务器需要实时发送多媒体数据,以及在通信会话期间需要从哪个服务器接收。

重要的是要了解,现在它已成为组织通信的备用方法。 TURN服务器应该非常可靠,具有大带宽和强大的计算能力,并支持处理潜在的大量数据。 因此,使用TURN服务器显然会导致额外成本,并增加系统的复杂性。

WebRTC API


WebRTC中存在三类主要的API:

  • Media Capture and Streams API负责媒体捕获和流传输。 使用此API,您可以连接到输入设备,例如麦克风和网络摄像头,并从它们接收媒体流。
  • RTCPeerConnection API 使用此类API,可以从WebRTC的一个端点通过Internet实时将捕获的音频或视频数据流发送到WebRTC的另一个端点。 使用此API,您可以在本地计算机和远程对等方之间创建连接。 它提供了用于连接到远程对等方,管理连接以及监视其状态的方法。 它的机制用于关闭不必要的连接。
  • RTCDataChannel API 该API表示的机制允许传输任意数据。 每个数据通道都与RTCPeerConnection接口关联。

让我们来谈谈这些API。

API媒体捕获和流


Media Capture and Streams API(通常称为Media Stream API或Stream API)是一种API,支持处理音频和视频数据流以及使用它们的方法。 使用此API,您可以设置与数据类型相关的限制,这里有使用异步机制处理数据时使用的回调,用于成功和不成功地完成操作,以及在操作过程中引发的事件。

getUserMedia() API的getUserMedia()方法询问用户是否允许使用输入设备,这些输入设备生成带有音频或视频轨道且包含所请求的媒体类型的MediaStream流。 这样的流可以包括例如视频轨道(其源可以是硬件或虚拟视频源,例如摄像机,录像机,屏幕共享服务等),音频轨道(物理或虚拟音频源可以类似地形成, (如麦克风,模数转换器等)以及其他类型的音轨。

此方法返回解析为MediaStream对象的Promise 。 如果用户拒绝许可请求或相应的媒体不可用,则将分别使用PermissionDeniedErrorNotFoundError来解决诺言。

您可以通过navigator对象访问MediaDevice单例:

 navigator.mediaDevices.getUserMedia(constraints) .then(function(stream) { /*   */ }) .catch(function(err) { /*   */ }); 

请注意,在调用getUserMedia()方法时,需要向其传递一个constraints对象,该对象告诉API应该返回哪种类型的流。 在这里,您可以配置很多东西,包括您要使用的摄像头(前置或后置),帧频,分辨率等。

从版本25开始,基于Chromium的浏览器允许您将音频从getUserMedia()传输getUserMedia()音频或视频元素(但是请注意,默认情况下将禁用媒体元素)。

getUserMedia()方法还可以用作Web Audio API的输入节点

 function gotStream(stream) {   window.AudioContext = window.AudioContext || window.webkitAudioContext;   var audioContext = new AudioContext();   //  AudioNode     var mediaStreamSource = audioContext.createMediaStreamSource(stream);   //       ,    ,   //       !   mediaStreamSource.connect(audioContext.destination); } navigator.getUserMedia({audio:true}, gotStream); 

与保护个人信息有关的限制


未经授权从麦克风或摄像机捕获数据会严重干扰用户的个人生活。 因此,使用getUserMedia()可以实现非常具体的要求,以通知用户正在发生的事情以及管理权限。 在打开任何收集媒体的输入设备(例如网络摄像头或麦克风)之前, getUserMedia()方法必须始终获得用户许可。 浏览器可以提供对域的一次性设置权限的选项,但是浏览器至少在第一次访问媒体设备时需要请求权限,并且用户必须明确地授予此类权限。

另外,与通知用户发生的事情有关的规则在这里很重要。 浏览器需要显示指示使用麦克风或相机的指示器。 这种指示器的显示不取决于系统中是否存在指示此类设备操作的硬件指示器。 此外,浏览器应显示一个指示符,表明已授予使用输入设备的权限,即使在某个时间点未使用该设备来记录相关数据也是如此。

RTCPeerConnection接口


RTCPeerConnection接口是本地计算机和远程对等方之间的WebRTC连接。 它提供了用于连接到远程系统,支持连接和监视其状态以及在不再需要连接之后关闭连接的方法。

这是一个WebRTC架构图,展示了RTCPeerConnection的作用。


RTCPeerConnection角色

从JavaScript的角度来看,可以从对该图的分析中得出的主要知识是RTCPeerConnection使Web开发人员从位于系统更深层的复杂机制中抽象出来。 即使使用不受信任的网络,WebRTC所使用的编解码器和协议也能出色地实现实时数据交换。 以下是这些机制解决的一些任务:

  • 掩盖数据包丢失。
  • 回声消除。
  • 带宽适应。
  • 动态缓冲消除抖动。
  • 自动音量控制。
  • 降噪和抑制。
  • “清洁”图像。

RTCDataChannel API


与音频和视频数据一样,WebRTC支持其他类型数据的实时传输。 RTCDataChannel API允许您组织任意数据的P2P交换。

有许多使用此API的方案。 以下是其中一些:

  • 游戏类
  • 实时文本聊天。
  • 文件传输。
  • 分散网络的组织。

该API旨在最有效地使用RTCPeerConnection API的功能,并允许您在P2P环境中组织功能强大且灵活的数据交换系统。 其功能包括:

  • 使用RTCPeerConnection有效地处理会话。
  • 通过优先级支持多个同时使用的通信通道。
  • 支持可靠和不可靠的消息传递方法。
  • 内置安全管理(DTLS)和拥塞。

这里的语法类似于使用WebSocket技术时使用的语法。 send()方法和message事件在此处应用:

 var peerConnection = new webkitRTCPeerConnection(servers,   {optional: [{RtpDataChannels: true}]} ); peerConnection.ondatachannel = function(event) {   receiveChannel = event.channel;   receiveChannel.onmessage = function(event){       document.querySelector("#receiver").innerHTML = event.data;   }; }; sendChannel = peerConnection.createDataChannel("sendDataChannel", {reliable: false}); document.querySelector("button#send").onclick = function (){   var data = document.querySelector("textarea#send").value;   sendChannel.send(data); } 

现实世界中的WebRTC


在现实世界中,WebRTC通信需要服务器。 系统不太复杂;由于有了这些系统,可以执行以下操作序列:

  • 用户彼此发现并交换彼此的信息,例如姓名。
  • WebRTC客户端应用程序(对等)交换网络信息。
  • 对等方交换有关媒体数据的信息,例如视频格式和分辨率。
  • WebRTC客户端应用程序绕过NAT网关和防火墙建立连接。

换句话说,WebRTC需要四种类型的服务器功能:

  • 发现用户并组织其交互的方式。
  • 发信号。
  • 绕过NAT和防火墙。
  • 无法建立P2P连接时使用的中继服务器。

ICE使用STUN协议及其TURN扩展来使RTCPeerConnection能够与NAT旁路机制一起使用,并应对通过网络传输数据时遇到的其他困难。

如前所述,ICE是用于连接对等方(例如两个视频聊天客户端)的协议。 在通信会话的最开始,ICE尝试通过UDP以尽可能少的延迟直接连接对等方。 在此过程中,STUN服务器只有一项任务:让NAT后面的对等方了解其公共地址和端口。 看一下可用的STUN服务器的列表 (Google也有这样的服务器)。


STUN服务器

ICE候选检测


如果无法建立UDP连接,则ICE尝试建立TCP连接:首先-通过HTTP,然后-通过HTTPS。 如果无法建立直接连接-特别是由于无法绕过公司NAT和防火墙,则ICE使用TURN服务器形式的中间设备(中继)。 换句话说,ICE将首先尝试将STUN与UDP一起用于对等方的直接连接,如果这不起作用,它将使用回租选项和TURN服务器形式的租用者。 术语“候选搜索”是指搜索网络接口和端口的过程。


寻找合适的网络接口和端口

安全性


实时通信应用程序或相关插件会导致安全问题。 特别是,我们在谈论以下内容:

  • 未加密的媒体数据或其他数据可能会沿着浏览器之间或浏览器与服务器之间的路径被拦截。
  • 应用程序可以在用户不知情的情况下,将视频和音频数据记录并传输给攻击者。
  • 病毒或其他恶意软件与外观无害的插件或应用程序一起可以进入用户的计算机。

WebRTC具有旨在应对这些威胁的几种机制:

  • WebRTC实现使用诸如DTLSSRTP之类的安全协议。
  • 对于WebRTC系统的所有组件,必须使用加密。 这也适用于信令机制。
  • WebRTC不是插件。 WebRTC组件在浏览器沙箱中运行,而不是在单独的进程中运行。 更新浏览器时,组件也会更新。
  • 必须明确授予使用摄像头和麦克风的权限。 并且,当使用摄像头或麦克风时,此事实会清晰显示在浏览器用户界面中。

总结


对于在浏览器之间实时传输任何数据的项目,WebRTC是一项非常有趣且功能强大的技术。 该材料的作者说,他的公司SessionStack使用传统的机制与用户交换数据,涉及服务器的使用。 但是,如果他们使用WebRTC来解决相应的问题,则可以直接在浏览器之间组织数据交换,从而减少数据传输的延迟并减轻公司基础架构的负担。

亲爱的读者们! 您在项目中使用WebRTC技术吗?

Source: https://habr.com/ru/post/zh-CN416821/


All Articles