Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RealTime Web II - WebRTC tech #41

Open
abbshr opened this issue Mar 5, 2015 · 0 comments
Open

RealTime Web II - WebRTC tech #41

abbshr opened this issue Mar 5, 2015 · 0 comments

Comments

@abbshr
Copy link
Owner

abbshr commented Mar 5, 2015

作为一个变革Web2.0的主力军, WebRTC赋予了浏览器之间实时通信(Real Time Communication)的能力, 提供了比WebSocket更加丰富的展现形式: 实时媒体流. 再去看看HTML5带来的Media API, 不难得出多媒体网络的特性正在逐渐与传统的Web融合的结论. 所以现在有必要研究一下多媒体Web的载体WebRTC了.

首先, 它是做什么的? 这里引用来自WebRTC官网的一段话:

WebRTC offers web application developers the ability to write rich, realtime multimedia applications (think video chat) on the web, without requiring plugins, downloads or installs. It's purpose is to help build a strong RTC platform that works across multiple web browsers, across multiple platforms.

顺便再盗他们一张图:
webrtc

这个图画的不错, 很直观地告诉我们WebRTC的宏观工作原理与技术栈的划分. 并说明一件事: WebRTC并非单一协议, 而是一种综合的技术!

只要支持WebRTC的浏览器都实现了WebRTC的底层系统. 包括:

  • 会话管理: 抽象会话层, 用于呼叫的建立与管理. 这一层允许开发者自己选择合适的协议, 如SIP, JSEP, SDP.
  • SCTP/RTP协议: 用于多媒体网络中实时数据交互的协议.
  • 内网穿透: STUN/TURN, ICE服务器. 负责P2P架构的实现.

有了这些保障, 浏览器之间就可以毫无阻碍的直接交流了.

真的是P2P?

没错. 浏览器之间确实可以点对点连接, 也确实符合P2P体系结构. 那么上面怎么提到需要STUN/TURN, ICE服务器? 答案是"为了获取端系统的IP地址以便开始P2P连接".

NAT

先来看看STUN, TURN和ICE都能做什么, 以下引用自Wikipedia

首先是STUN:

STUN(Session Traversal Utilities for NAT,NAT会话传输应用程序)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。

其次TURN:

TURN(全名 Traversal Using Relay NAT),是一种资料传输协议(data-transfer protocol)。允许在TCP或UDP的连线上跨越 NAT 或防火墙。
TURN是一个client-server协议。TURN的NAT穿透方法与STUN类似,都是通过取得应用层中的公有地址达到NAT穿透。但实现TURN client的终端必须在通讯开始前与TURN server进行交互,并要求TURN server产生"relay port", 也就是relayed-transport-address。这时 TURN server会建立peer, 即远端端点(remote endpoints), 开始进行中继(relay)的动作,TURN client利用relay port将资料传送至peer, 再由peer转传到另一方的TURN client。

还有一段对STUN和TURN比较清楚的描述:

  • A STUN server is used to get an external network address.
  • TURN servers are used to relay traffic if direct (peer to peer) connection fails.

Every TURN server supports STUN: a TURN server is a STUN server with added relaying functionality built in.

最后是ICE:

交互式连接建立(Interactive Connectivity Establishment),一种综合性的NAT穿越的技术。
交互式连接建立是由IETF的MMUSIC工作组开发出来的一种framework,可整合各种NAT穿透技术,如STUN、TURN(Traversal Using Relay NAT,中继NAT实现的穿透)、RSIP(Realm Specific IP,特定域IP)等。该framework可以让SIP的客户端利用各种NAT穿透方式打穿远程的防火墙.

我们能从上面的引用中总结如下信息:

  1. P2P模式中可能会碰到需要内网与外网建立连接的情况.
  2. 建立P2P连接需要互相知道对方的实际IP地址和端口号.
  3. WebRTC的会话建立阶段可能会需要防火墙穿透.
  4. WebRTC的实现需要防火墙穿透技术的辅助.
  5. WebRTC在通信上基于UDP协议.

这说明直连是有代价的. 在进行实际通讯之前, 可能需要外部STUN等服务器的帮助.

如果不用NAT就不需要服务器吗?

RT, 回答是"No". 下面来看看完成一个peer的建立还要有什么保障.

WebRTC need server for clients to exchange metadata to coordinate communication.

如果了解多媒体网络, 你应该已经猜到了这一环节, 它被称做signaling(信令交换).

信令交换都做些什么?

  • Session control messages used to open or close communication.
    Error messages.
  • Media metadata such as codecs and codec settings, bandwidth and media types.
  • Key data, used to establish secure connections.
  • Network data, such as a host's IP address and port as seen by the outside world.

由此可见, signaling的目的和SIP协议类似, 负责会话建立与管理等控制性工作, 属于"out-of-band communication"(带外通信).

但遗憾的是, WebRTC标准中并未实现signaling, 而是把他交给了应用开发者去实现. 与其说是遗憾, 不如说是灵活, 因为这样就允许我们自己选择合适的协议或技术来完成信令交换.

different applications may prefer to use different protocols, such as the existing SIP or Jingle call signaling protocols, or something custom to the particular application.

JSEP就是完成这个目的的一个信令协议. 盗HTML5Rocks一张图, 说明了JSEP及信令交换的体系结构:

jsep

JSEP需要一对peer之间交换"offer"数据和"answer"数据, 对应呼叫发起者和被叫者. 两种报文以SDP协议描述的指定格式封装, 例如:

v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2

SDP格式的信息允许开发者在设置SessionDescription前修改的, 例如改变视频/音频编码格式.

peer发现

说了这么多, 还有一个关键问题尚未解决: 对等设备是如何找到目标的呢? IP地址? alias? 其实没有明确的规定. 为了说明peer发现的手段, 这里借用SIP的peer发现流程解释一下.

如果呼叫方已经知道了对方的IP地址, 那么一切好办. 但是这个假设很不现实, 不仅因为IP地址是动态分配的, 而且对方可能有多个网络设备, 更何况如何在茫茫大海中寻找那个独一无二的IP呢? 最好有一种办法, 使用对方的"别名"就能够达到寻址的目的.

幸运的是, 这个想发是可以实现的. 在SIP中, 呼叫方可以创建一个包含对方的别名的SIP报文, 发送到SIP代理, 该代理将以一个SIP回答来响应.回答可能包含对方正在使用设备的IP或其他设备IP, 也可以是其他信息, 就像DNS服务器一样.

那么SIP代理服务器是如何做到IP地址解析的呢? 为了解决这个问题, 需要一个SIP注册器. 每个用户都有一个SIP注册器, 任何时候用户在设备上发起SIP应用时, 会给该注册器发送一个SIP注册报文, 向注册器通知其IP地址. 任何时候更换一个新的设备, 都会再次向SIP注册器发送一个新的注册报文. 如果长时间使用一个设备, 设备将周期性发送刷新报文, 以指示发送的地址仍然有效.

WebRTC工作流程

  1. 向会话管理层的注册器注册本地设备的IP等网络信息
  2. 调用WebRTC浏览器API进行对等设备连接.
  3. 底层API进行本地媒体及网络的探查, 并构造SDP报文, 设置Session Description.
  4. 构造offer报文
  5. ICE框架去检查目标是否可以建立连接.
  6. 如果可以, 返回对等方的IP等信息, 把offer报文发过去
  7. 对于对等方, 当接收到offer报文, 也会根据SDP设置Session Description
  8. 对等方构造answer报文, 并响应回去.
  9. 此时双方协商好了通信基础, 于是开始使用SCTP/RTP协议进行实时数据交互.
  10. 任意一方可以随时发送终止会话报文结束会话.

(signal服务器, 多播, 浏览器API将在下一篇里说明.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant