如何调试WebRTC

自成立以来,Voximplant一直在使用WebRTC:首先作为Flash的替代产品进行语音和视频通话,然后完全替代。 这项技术的发展道路漫长而痛苦,直到最近所有主要的浏览器都开始支持该技术,屏幕传输,多个视频流都遇到了困难,有时仅关闭并打开视频流就会使浏览器崩溃。 积累的经验使我们能够为Habr翻译有趣的文章,今天,我们将这个词传递给Xirsys的Lee Sylvester,他将讨论在Chrome,Firefox,Safari和Edge中进行调试(视频)调用的过程。 调试WebRTC并不容易,我们甚至针对删除流行浏览器中的日志提供了特殊说明 。 Lee拥有的一切-您会发现削减的地方(剧透:很多东西,包括WireShark)。


WebRTC的阴暗面


在Xirsys工作时,我看到了一些使用WebRTC的超酷应用程序。 但是,尽管一小群开发人员创建了高科技产品,但大多数程序员甚至无法开始使用WebRTC。 怎么了 一切都很简单。 这很复杂。

我们许多人都熟悉典型的Web应用程序。 这样的应用程序具有发送请求的客户端和响应这些请求的服务器。 一个简单,线性且易于预测的过程。 如果出现问题,我们通常知道在哪里查看日志以及可能发生的情况。 但是使用WebRTC,一切都不是那么简单。

异步性


如果您曾经编写过多线程应用程序,那么您可能知道这种开发带来的麻烦。 飞行,糟糕的记忆-但大多数情况下只是难以发现的错误。

WebRTC本质上是异步的。 这根本不是简单的AJAX异步。 打个比方,这些是同时启动的几个AJAX请求,它们试图使两台计算机上的数据一致。 那仍然是娱乐。

NAT绕过雷区


创建Web应用程序归结为开发可在服务器上运行并响应请求的内容。 可能发生的最糟糕的事情是IPTables中未打开的端口。 它在2分钟内得到处理。 您不能说WebRTC。

Web服务器,甚至不是其软件,而是硬件,都是具有公共IP地址的设备。 它们可以从任何地方访问。 WebRTC可以从用户的计算机发送和接收数据。 IP地址通常为192.168。Something,并且不会因响应网络请求而燃烧。

WebRTC的作者对此很了解,因此引擎将对不同的连接方法进行分类,以试图在两台不是专门为此设计的计算机之间建立连接。

从哪里开始调试


在本文中,我将讨论解决最流行问题的基本工具。 但是在此之前,让我们看看WebRTC通常如何建立连接。

WebRTC如何建立连接


所有WebRTC连接都需要信令协议的帮助。 “一点帮助”是您自己的服务器和协议,呼叫者可以在建立对等连接之前与之通话。

WebRTC将使用信令协议传输有关IP地址的信息,捕获和播放语音和视频的能力,网络拓扑以及传输的数据。

常用的协议是COMET(或SIP-译者注)和Web套接字。 WebRTC不会将开发人员限制为任何事物,因此您可以随意使用,至少可以通过记事本传输数据并复制粘贴(在其中一个研讨会上完成,它可以工作-还是翻译器)。 连接到两台计算机的信号允许您已经通过WebRTC启动连接。

提供和回答


WebRTC连接使用“要约”和“答案”:

  1. 连接的发起者创建并传递到另一侧“要约”。
  2. 对方收到“要约”,创建“响应”,然后将其传递回去。
  3. 连接的发起者会收到一个“答案”。

从理论上讲。 实际上,礼貌交流看起来并不那么简单。

  1. 在发送“要约”之前,连接启动器创建RTCPeerConnection的实例,并使用rtcPeerConnection.createOffer() 从中接收文本包“ SDP”(会话描述协议 ; 该软件包描述了为浏览器接收/传输语音和视频的功能。
  2. 使用rtcPeerConnection.setLocalDescription()将SDP包的内容设置为“连接本地端的描述”。
  3. 数据包被发送到另一端,使用rtcPeerConnection.setRemoteDescription()将其内容设置为“连接另一端的描述”。
  4. 在连接的另一端,使用rtcPeerConnection.createAnswer()创建了自己的SDP包,其内容设置为“连接本地端的描述”。
  5. 数据包被传递到连接启动器,连接启动器将其内容设置为“连接另一端的描述”。

而且,只有在完成所有操作之后,连接双方才知道彼此接收和发送语音/视频的能力。

ICE候选人


但是,与媒体合作的能力还不够。 毕竟,缔约双方尚未透露有关网络状态的任何信息。

您可以立即了解浏览器支持哪些视频编解码器,以及笔记本电脑上是否有摄像头。 查找外部IP地址和NAT操作的逻辑需要花费时间,并且在收到此信息时会交换有关网络状态的信息。

借助Trickle ICE技术(并非所有浏览器都支持-译者注),只要找到合适的“候选人”,就可以随时建立两个WebRTC设备之间的连接。

开发人员必须订阅onicecandidate事件(全部为小写!),然后将接收到的SDP数据包传递到另一端,在此需要WebRTC使用addIceCandidate方法传输它们(此处用大写字母表示)。 它可以双向工作。

连接方式


WebRTC使用诸如STUN(用于NAT的会话遍历实用程序)和TURN(用于在NAT周围进行中继的遍历)之类的东西来建立连接。 听起来很吓人,但实际上只有两种网络协议。

STUN服务器


这两个协议中的第一个比回显服务器要复杂一些。 当连接参与者想要描述如何与他们连接时,他们需要他们的公共IP地址。 而且很可能不是计算机的IP地址,公共设备很少分配给用户设备。 发明了整个NAT技术,以免相互隔离。 为了仍然找到您的公共地址,浏览器向STUN服务器发出请求。 通过NAT,网络数据包将其返回地址更改为public。 接收到带有请求的数据包后,STUN服务器会将数据包的返回地址复制到其有效负载中,然后将数据包发送回去。 数据包以相反的方向通过NAT,丢失了其公共IP地址,但是此地址的副本保留在有效负载中,WebRTC可以在其中读取它。


TURN服务器


TURN服务器使用STUN协议扩展。 相同的包,标头和一个新东西: command 。 服务器是代理:两个客户端都通过UDP 分配端口连接到它,并通过服务器传输其数据。

TURN服务器的设计方式是,连接的发起者比另一端具有更多的功能。 当通过TURN服务器进行的呼叫成功或失败时,这会产生有趣的效果,具体取决于谁在呼叫谁(记住所有Skype-注释转换器)。


侦错


因此,您阅读了本段。 我们对翻译感到满意,并记住该文章是关于调试WebRTC的。 但是以上所有都是必要的最低要求,没有它,您甚至无法启动。 但是,如果您开始,并且没有不人道的运气,那么它将破灭。

它将以许多不同的方式破裂。 第一个是缺乏连通性。 您将STUN和TURN服务器设置都传递给了两个WebRTC,帮助它们交换报价,答案和ICE候选人,但是没有视频或语音。 从哪里开始? 带有本地播放问题。

WebRTC本地调试


就像我在上面写的,WebRTC的主要工作发生在浏览器端。 STUN和TURN服务器非常简单,因此大多数问题都发生在运行两个浏览器的JavaScript代码中。 悲伤但真实。 另一方面,如果最有趣的事情发生在本地浏览器中,那么您就有足够的机会进行调试!

首先要检查的是您的信号。 这是您的代码,可在浏览器之间传输带有视频的音频配置(要约,答案)以及有关网络设置的信息(候选冰)。 您需要检查发送了哪些数据包,接收和发送了哪些WebRTC:

  • 连接的另一端收到了要约? 连接发起者是否收到响应? 如果没有这种最少的便利设施交换,就不会建立连接。
  • 连接两端的WebRTC是否向您传递带有ICE候选数据包? 您是否交换了这些数据包,并使用addIceCandidate将其传递回另一侧?
  • 如果数据包交换一切正常,是否调用onaddstream事件处理程序,您是否将结果对象安装在HTML元素中以播放视频(或音频)?

如果数据包交换不是可疑的,则可以深入探讨会话的内容。

会话描述协议


WebRTC以SDP文本格式创建了Offer,Answer和ICE候选软件包。 乍一看,这些软件包的内容看起来很吓人,但是只要稍加准备,您就可以在调试期间从中受益匪浅。 Wikipedia很好地描述了SDP,但我为您找到了更好的描述

候选ICE SDP数据包中最重要的字段是typ 。 对于WebRTC,字段可以具有以下三个值之一:

  • 典型主机;
  • typ srflx;
  • 典型继电器。

典型主机


主机类型指定用于本地连接的ICE候选对象(WebRTC枚举了多个候选对象,希望建立连接,但事先不知道会出现哪种候选-译者注)。 这样的连接不需要STUN或TURN服务器,因为本地网络中的设备通常可以直接建立网络连接。 从本地网络调试时,您只需要检查和调试主机数据包的传输,并确保设备可以相互发送UDP数据包。 尽管有例外,但实际上,我已经看到了网络配置,其中浏览器需要TURN服务器才能将...连接到自身。

打字机


字母“ srflx”的组合表示“ Server Reflexive”,并使用外部IP地址标记候选连接,其中STUN服务器足以进行连接(使用NAT渗透技术,在大约80%的情况下成功,请注意翻译者)。

典型继电器


“中继”标记通过TURN服务器的连接,几乎总是成功。 重要的是要记住,不需要WebRTC来创建带有“ typ”字段的三个完全不同的程序包。 如何选择候选人取决于特定浏览器版本中WebRTC的实现。

测试设备连接


Google提供了专用的Web应用程序来测试您设备上的WebRTC连接。 打开页面,单击“开始”按钮,JavaScript代码将尝试使用信号传输,Google的STUN和TURN服务器建立与Google服务器的连接。

WebRTC内部


您检查了所有软件包,检查了代码,一切看起来都正确,但是不起作用? 对于这种情况,Google在其Chrome浏览器中提供了一个特殊部分,该部分显示了连接设置过程中WebRTC的内部情况,并在连接成功的情况下提供了一些精美的图表。 要使用,请在浏览器中打开特殊的技术链接:

chrome://webrtc-internals

如果您已经有一个使用WebRTC打开的应用程序,则将立即看到大量技术数据。 否则,只需打开另一个选项卡,其中就会使用WebRTC。 该选项卡显示对RTCPeerConnection对象的所有调用,并允许您实时查看如何建立连接。

ICE设置


页面顶部是用于初始化连接的ICE字符串。 如果在错误形成期间发生错误,则将立即可见(作者通过“ ICE行”,使用STUN和TURN服务器列表(“ iceServers”对象)引用RTCPeerConnection对象的配置-译者注)。 也许没有服务器列表? 在首次调用createOffercreateAnswer之前,必须配置RTCPeerConnection对象。


RTCPeerConnection事件


下一个内部部分将按时间顺序显示对RTCPeerConnection方法的调用以及从对象接收的事件。 错误会以红色仔细突出显示。 请注意,红色的addIceCandidateFailed通常并不表示错误,并且连接可以正常建立。 如果连接成功,则列表中的最后一个事件将是iceconnectionstatechange事件,其值为complete

“统计”部分


下一部分与成功建立连接有关。 它包含传输数据和网络延迟的统计信息。 最有趣的两个选项是: ssrcbweforvideo

  • ssrc (“流源”)标记每个音频和视频轨道。 显示传输数据的统计信息和往返时间等参数;
  • bweforvideo (带宽估计)显示使用的网络通道的宽度。


GetStats函数


通常,您将无法访问内部页面。 例如,当您的用户出现问题时。 在这种情况下,可以通过调用RTCPeerConnection对象上的getStats方法来获取与内部页显示的数据相同的数据。 此方法设置了一个回调函数,每次发生有趣的事情时WebRTC都会调用该函数。 调用的函数获取一个对象,该对象具有内部页面显示的字段:

 rtcPeerConnection.getStats(function(stats) { document.getElementById("lostpackets").innerText = stats.packetsLost; }); 

另一个有用的工具是RTCPeerConnection对象的oniceconnectionstatechange事件。 事件处理程序将接收连接进度信息。 可能的选择:

  • new :WebRTC期望来自连接第二面的候选对象,必须使用addIceCandidate方法添加候选对象
  • 检查 :WebRTC从连接的第二端收到候选者,将它们与本地候选者进行比较,并遍历选项;
  • 已连接 :选择一对合适的候选者并建立连接。 值得注意的是,此后,候选人可以按照Trickle ICE协议继续参加;
  • 已完成 :已收到所有候选人并建立了联系。
  • 断开连接 :连接已断开 。 在不稳定的频道上,WebRTC能够重新连接自身,我们监视连接的标志;
  • 已关闭 :连接已断开,WebRTC不再适用。

如果连接以失败状态结束,那么我们可以检查双方收到的候选对象并了解连接失败的原因。 例如,如果一侧提供了hostsrflx候选者 ,则另一侧提供了hostrelay ,但设备位于不同的网络上。

黑色矩形代替视频


通常,建立连接时会传输声音,但是一个或两个参与者都有一个黑色矩形,而不是视频。 如果在连接转换为完成状态之前将接收到的视频对象分配给HTML元素,则通常会发生这种情况。

如何在外面戳魔杖


除了RTCPeerConnection对象本身和浏览器显示的内部信息外,您还可以使用网络数据包分析工具,例如Wireshark。 这些工具可以显示使用过的WebRTC协议的数据包。 例如,Wireshark将在主窗口中向您显示STUN数据包的内容,您可以通过在过滤器字段中键入关键字“ stun”来过滤它们:


在服务器响应中要看什么? 如果仅看到绑定类型的答案,则意味着仅支持STUN(外部IP对话),并且WebRTC仅提供srflx候选对象。 如果答案包含TURN特定的包AllocationCreatePermission ,则WebRTC将有机会尝试通过代理服务器进行连接。 数据包分析器标记成功和不成功的分配 。 如果没有成功,则很可能传递了对TURN服务器的错误访问参数(几乎总是使用用户名和密码(译者注)进行保护)。

如果日志中有一个CreatePermission成功响应包,那么我们可以假定STUN和TURN配置一切正常。 并且,如果还有ChannelBind软件包,则可以高速建立与TURN服务器的连接。

手机问题


在我的实践中,许多建立WiFi连接的WebRTC解决方案无法通过3G / 4G连接。 在移动设备上启动的应用程序更难调试:我们没有Wireshark这样简单的数据包分析器,而Safari无法显示WebRTC内部。 逻辑建议,如果应用程序通过WiFi可以正常工作,则问题不在于应用程序本身,而在于蜂窝通信。 如何调试? 拿一台笔记本电脑,然后将3G加密狗连接到它。 因此,您有一个数据包分析器和便捷的日志,可以在合理的时间内找到所有麻烦的根源。

结论


调试WebRTC并不容易,但是如果您在Internet上搜索良好,则可以找到许多文章和示例。 如果您从事实时通信领域的工作,那么我建议您阅读STUNTURN协议和WebRTC技术的RFC规范。 这些文件很大,但其中包含的信息有助于做出可靠的决定并回答“为什么不响”的问题。

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


All Articles