Cliff的工作室
WebRTC怎么用

背景就不多说了,无非是程序员的无聊吐槽,大家用手指头想想也知道是怎么回事。

问:WebRTC是什么? 答:是浏览器实现的一套用于p2p连接的接口。

看到主谓宾了吧。WebRTC是......接口(也可以说是标准啦)。所以不要以为它是架构,或者是工具库(当然它包含native接口库),或者是什么万能灵药。

问:WebRTC包含什么? 答:三个接口。getUserMedia负责获取多媒体流;RTCPeerConnection负责点对点连接;RTCDataChannel负责数据传输。

有点程序员常识的看明白了吧。就这三个接口,而且还都是前端用的,就只能干这三个接口的事。光用前端就搞出一套基于Web的即时通讯软件,还不建服务器。拜托,在这个年代,这不是计算机软件,这是神迹。

问:那好吧,做一套基于Web的即时通讯软件还需要什么? 答:那得看你真正需要什么。架构是为了需求服务的,又想灵活,又想强大,还又想少写代码,只能等会编程的人工智能出现了。

不吐槽了,还是实务一点。 问:用WebRTC接口,如何建立RTCPeerConnection? 答:这是一系列动作

graph TB subgraph 接收者 B1["new PeerConnection()"] --> B2["onicecandidate=gotLocalIceCandidate(event)"] B2 -.- B3["setRemoteDescription(description)"] B3 --> B4["createAnswer(gotAnswerDescription)"] B4 --> B5["gotAnswerDescription(description)"] B5 --> B6["setLocalDescription(description)"] B6 --> B7["sendMsg(JSON.stringify(description))"] B7 -.- B8["gotLocalIceCandidate(event)"] B8 --> B9["sendMsg(JSON.stringify(event.candidate))"] B9 -.- B10["addIceCandidate()"] end subgraph 发起者 A1["new PeerConnection()"] --> A2["onicecandidate=function"] A2 --> A3["createOffer(gotLocalDescription)"] A3 --> A4["gotLocalDescription(description)"] A4 --> A5["setLocalDescription(description)"] A5 --> A6["sendMsg(JSON.stringify(description))"] A6 -.- A7["setRemoteDescription(description)"] A7 -.- A8["gotLocalIceCandidate(event)"] A8 --> A9["sendMsg(JSON.stringify(event.candidate))"] A9 -.- A10["addIceCandidate()"] end A6 --> B3 B7 --> A7 A9 --> B10 B9 --> A10

很明显,要建立P2P连接,先得有一个机制,让双方可以双向通信(如图中的sendMsg),这就是所谓信令服务。现在很多sample都是用socket.io建立一个service,通信双方通过同一个url进入同一个room,然后通过这个room中转信息。只是这种做法不适合商用。因为url也是需要通讯的。

理解上面的流程之后,就可以发现,实际上问题已经转化了。先有鸡还是先有蛋?或者说,先有信令服务还是先有WebRTC。

答案是明显的,信令服务是必须的。哪怕是像例子程序一样凑合一个不完整的信令服务器出来。html5rocks网站上有一篇文章讲的比较明白。信令服务现在有几种做法:

对于个人而言,我觉得第一条路子比较容易搭起来,资源比较多。

有了信令服务,配合比较新的browser,按照上面的流程图,局域网里面的WebRTC通讯基本就没什么问题了。对于Internet,需要STUN/TURN服务。找一台有公网IP的机器,配好rfc-5766-turnserver,并将url加入web应用即可。

总而言之,要做Web的视频通讯,只有WebRTC是不够的。至少还要有信令服务器和STUN/TURN服务器。WebRTC只关心视频通讯的部分。真正的通讯,是从信令服务开始的。

2015 年 01 月 11 日 16 时 16 分