webrtc早期总结

注:此为早期的对于webrtc实现的一份总结

绪论

  Webrtc 全称为web real-time communication,也即是支持web上实时通讯,而且它包括几乎所有我们想用到的东西:视频、音频、文字、文件的实时通讯。相比我们以前常用的QQ、sms等等,Webrtc最大的特性就在于它是基于网页的,只需要打开网页就可以和其它人进行联系。我们知道传统的Web中是没有推送这个概念的,所以就会有使用ajax轮询、使用flash的 xml socket等方式来和服务器进行数据交互,直到HTML5的websocket的出现,才让这个推送问题得到更好的解决。比较一下websocket和webrtc,虽然它们都可以进行在线的通讯,但websocket更多的是浏览器和服务器间的通讯,webrtc则主要注重于浏览器和浏览器之间的通讯。可以想象,两个用户之间进行通讯而不需要经过服务器中转,这会减轻多少服务器的负担。

在Webrtc中,走在最前面的是Google。Google在2010年收购了Global IP Solution的GIPS引擎,改名成webrtc,并将它进行开源,从而才会推动webrtc的发展。Chrome浏览器也是率先提供对webrtc各种特性的支持,比如screen share(用户屏幕分享),目前这个只在Chrome浏览器中得到支持。

Webrtc开发:

  Webrtc的理念很好,但我们应该更加关注于目前现有的技术状况。

  在前端:目前Webrtc提供了MediaStream、RTCPeerConnection、RTCDataChannel三类主要的API:其中MediaStream主要用于获取数据流,比如用户的摄像头、麦克风的数据流,RTCPeerConnection主要用于两个用户间建立连接并传输视频、音频数据。RTCDataChannel主要用于常用的数据进行通讯,比如发送文字、传输文件等。值得注意的是目前webrtc的协议并没有正式的定下来,所以每个浏览器间都有自己的实现,这个实现通常都会加入自己的前缀,比如RTCPeerConnection在chrome浏览器命名为webkitRTCPeerConnection,在火狐浏览器中命名为mozRTCPeerConnection。

  在服务器端:虽然Webrtc是基于浏览器和浏览器之间通讯的,但是它还是需要用到服务器。服务器在两个用户连接之间充当中介的作用,用英文名称说法是signaling。双方通过服务器交换建立连接时需要用到的数据。比如,在双方初始化RTCPeerConnection的时候会同时创建一个session description(这个session description记录了自己本机的媒体数据,比如是否有视频传输啊,视频分辨率,网络ip等信息),之后通过服务器来交换该session description.当然,双方建立连接肯定需要交换网络信息,交换网络信息后还会使用ICE framework来对付NAT中转和防火墙。最后可能还需要一个TURN服务器来处理双方无法直接连接需要服务器作为中转的情况。

关于Screen Share:

  目前,我对于视频和音频上面的控制还不是很熟悉,这些的获取都是通过别人的类库去加载的,我并没有在上面进行过多的处理。不过我对于screen share进行了一下调查。貌似目前只有Chrome浏览器对screen share进行了支持,它调用的是chrome.desktopCapture.chooseDesktopMedia接口,但它还有诸多的约束,比如:要使用ssl安全连接,要在chrome://flags/中启用部分实验性功能,另外还需要安装插件,该接口是仅仅对于Chrome apps/extensions开放的,也就是只有插件才能调用该接口,想要在web上使用,需要使用postMessage和插件进行交互来获得screen share的数据流。

RTCDataChannel:

  目前我主要是基于RTCDataChannel上去开发。RTCDataChannel是基于RTCPeerConnection的基础上,针对于通用的数据(比如文本、文件)进行传输,据说比websocket延时要低(可能是考虑到不需要服务器中转,少了些“hops”。考虑到目前的网络状态,我觉得这要建立在双方机子的网络通讯良好的情况下说的,毕竟不同用户间直接相连进行传输肯定会有快有慢的)。RTCDataChannel主要使用的是SCTP协议,支持有顺序和无顺序的传输,支持重连。解题可以参考下表:(来源:http://www.html5rocks.com/en/tutorials/webrtc/datachannels/)

TCP UDP SCTP
Reliability reliable unreliable configurable
Delivery ordered unordered configurable
Transmission byte-oriented message-oriented message-oriented
Flow control yes no yes
Congestion   control yes no yes

  由上表可以知道SCTP协议对于可靠性、传输顺序等都支持可配置,看起来好像很好,但实际开发中,这也只能是针对于两人之间的通讯,在多人通讯的时候,传输顺序可能就不是我们所希望的了。

  在传输数据上,它的api和websocket比较相似,都有相似的onerror,onmessage,onopen,onclose等方法,调用起来不难。对于datachannel,一开始我以为就像之前使用cometd做的一样,只要建立了一个data channel,所有加入该通道的用户都可以直接群聊。但后来发现好像不是这样,data channel只是两个用户之间建立的一个数据通道。多用户的交流,还是要自己去定义和初始化RTCPeerConnection。比如你是希望每两个用户之间都建立一个连接,或者是建立星型连接(以一个用户为中心点,每个用户跟它相连,有点类似C/S模式)。

Signaling server:

  这个我叫它为信令服务器,为两个用户之间进行连接搭桥、牵线。这个信令服务器可以使用ajax方式、websocket方式等等。关于两个用户的信令交换部分,我觉得可能会比webrtc的接口使用要复杂。Webrtc并不包括signaling部分。目前我是使用了nodejs作为服务容器,使用websocket和浏览器进行通讯,这个信令服务器不包括Turn这部分。

关于多人通讯和聊天数据保存:

  Webrtc虽然是个web实时通讯的协议,但是它主要还是针对于两个用户间点对点的通讯,所以对于多人通讯,需要我们去维护这么多人之间的结构,比如采用星型、环形、树形、网型之类。多人聊天当中,又得考虑某个人退出的时候,拓扑结果如何变化等问题。对于聊天数据的保存,由于webrtc主要是浏览器之间进行的通讯,不经过服务器的中转,所以如果我们需要记录这些聊天信息的话,那我们需要建立其它的渠道。比如说,每发送一条消息都会在后台使用websocket和服务器进行通讯,那么这样就有一个问题,数据的保存,需要给每个消息分配一个id,但这个id的分配是一个问题,怎么保证id的唯一性。如果需要记录每个用户读了哪些消息哪些没读,这也是一个问题。另外使用nodejs作为信令服务器和我们之前用tomcat作为服务器之间的session要怎么保持一致的问题上也是个问题。现在只是继续调研webrtc到底能实现到哪些东西。

关于webrtc的框架:

  目前由于webrtc还不是很成熟,虽然受到关注,但是这方面的资料和成熟一些的框架都还很少,前面已经知道,每个浏览器都有自己的实现,方法的前缀不太一样,那么比较好的方法是找到一个框架能够同时兼容多个浏览器从而减少开发的麻烦。从开始接触到现在,也已经换过好几个框架了,有:simpleWebrtc,peerjs,RTCmultiConnection等。一开始用的是simpleWebrtc,因为刚开始接触时,在网页搜索时,这个比较出名,而且一直在更新,当时使用它很快的就实现了一个多人视频聊天的demo。但是有个问题就是它的文档很少,都不知道哪些api可用,怎么用。强行的去试着开发一段时间发现在上面进行二次开发真的不太容易。之后就接触到了peerjs,peerjs有着很简洁的逻辑,也有比较清晰的api,但是它有个问题,就是只能建立双人之间的连接,没有实现多人聊天。最后接触到了RTCmultiConnection,看到了有比较详细的文档,利用它还实现了文件传输、在线交流、音视频连接、screen share等。

Mikzone