最近在考虑把项目中的通知模块单独提取出来,做一些即时提醒,快速响应。由于访问量大了之后,Ajax轮询的方式发送的请求数太过庞大,所以考虑使用WebSocket来缓解压力,当然了,WebSocket可以做的事情可不止这些,今天首先来在各个技术之间做个对比,看看它牛掰的地方,有个大体的认识

比如这样的需求:

    使用WEB,来构建实时的展示页面来展示股票信息、火车票余票、医疗设备读取的信息,或是即时聊天等等

其实这些都是属于即时交互的需求,而WebSocket就是为了即时交互而设计的!

什么Polling、Long-Polling、FlashSocket。。。。在WebSocket真正到来之后都将成为过眼云烟~(此处是夸张的修辞手法~)

 

好,下面准备开始~~

 

WEB开发人员看到这个图总是会感觉很亲切,接下来我们就看看在这种请求响应模型中如何做到即时交互

 

Constantly Refresh

简述

    HTTP协议原本是设计用于传输简单的文档和文件,而非实时的交互。根据HTTP协议,一个客户端如浏览器,向服务器打开一个连接,发出请求,等待回应,之后关闭连接。如果客户端需要更多数据,则需要打开一个新连接,以此循环往复。如果服务器有了新的信息,它必须等待客户端发出请求而不是立即发送消息。

    举个例子:我(客户端)要从你(服务器)那运货,先修条路,然后派个使者去通知你要什么货,然后你把货给我送过来,最后把修好的路作废,再想运送别的货物,对不起,请重新修路那么要看到页面中要展示信息的最新情况,应该怎么办?不断刷新!是的,以前就是这么做的

评价

这种方式现在已经被完全淘汰,发送了很多不必要的请求,浪费大量带宽,页面不断刷新,用户体验差,而且做不到真正的实时,服务端有了新数据也不能立马推送给客户端,使得秒级的实时信息交互难以实现

 

Polling

简介

    这可以算是第一种风格的comet

    每隔一固定时间发送一个Ajax请求拉取数据,根据服务端返回的数据通过DOM操作做一些展现

评价

比不断刷新好一些,浏览器不用一闪一闪的重新加载了,而且只传送感兴趣的那一小部分数据,占用带宽变小。但是,客户端并不知道服务端什么时候准备好了自己感兴趣的数据,无法很好的设置轮询时间,只能根据经验设置一个固定的时间,这样就会发送很多不必要的请求

 

Long-Polling

简介

    这可以算作第二种风格的comet

    客户端发送一个request给服务端,服务端会在一个设定的时间段内保持这个request为打开状态,如果在这段时间内, 服务端程序收到一个notification,就会把携带了最新消息的response回送给客户端,如果在这个设定的时间内一直没有收到新消息,没有收到notification,服务端程序在时间到的时候同样会发送一个response给客户端

评价

    长轮询相对于一般轮询的优点在于,数据一旦可用,便立即从服务器发送到客户机。请求可能等待较长的时间,期间没有任何数据返回,但是一旦有了新的数据,它将立即被发送到客户机。因此没有延时这种情况在服务端消息比较少的情况下表现还不错,但是服务端有大量消息要推送的时候,Long-Polling与Polling相比,实际并没有什么本质的提高,它还是需要等待客户端的请求,然后才能发消息,而不是自动推送!

 

Streaming

简介

这是第三种风格的comet按照这种风格,服务器将数据推回客户机,但是不关闭连接。连接将一直保持开启,直到过期,并导致重新发出请求。XMLHttpRequest 规范表明,可以检查 readyState 的值是否为 3 或 Receiving(而不是 4 或 Loaded),并获取正从服务器 “流出” 的数据

评价

和长轮询一样,这种方式也没有延时。当服务器上的数据就绪时,该数据被发送到客户机。这种方式的另一个优点是可以大大减少发送到服务器的请求,从而避免了与设置服务器连接相关的开销和延时。但是,Streaming也是在HTTP的基础上做了包装,介入的防火墙和代理服务器会对response做缓存,增加了消息传输的延迟。所以,当遇到代理服务器做了缓存的情况,很多流式解决方案就会回退到Long-Polling方式。当然,TLS(SSL)连接可以用来逃避response被缓存,但是建立和销毁每个连接的代价实在太高了。另外不幸的是,XMLHttpRequest 在不同的浏览器中有很多不同的实现。这项技术只能在较新版本的 Mozilla Firefox 中可靠地使用。对于Internet Explorer 或 Safari,仍需使用长轮询

 

小结

    上面提到的所有的实时交互方式都会用到HTTP的请求头和响应头,它们包含有很多不必要的额外的信息以至于增加了延迟。

    其实全双工通信方式不仅是从服务端到客户端的下行数据流就可以解决的。在这半双工的HTTP基础上来模仿全双工通信,现在的一些解决方案是使用了两个连接:一个是下行数据流,一个是上行数据流。但是要维持这两个连接并且使之协同工作,不但非常复杂,而且需要消耗大量资源。简单说来,HTTP就不是为了实时和全双工通信而设计的。

    下图展示了创建一个WEB应用的复杂性,它是在HTTP之上,使用发布/订阅模型,从后端往前端传输实时数据

 

FlashSocket

 

简介

Socket 套接字连接允许Flash播放器通过指定的端口与服务器通信,socket连接与其他通信技术最大的不同是socket连接在数据传输完成后不会自动关闭。这个特点决定了它可以作为即时通信

评价

    FlashSocket透明地提供了WebSocket的功能,即使是在不支持HTML5 WebSocket的浏览器上也是如此

    FlashSocket有着下面的这些缺点:

    1). 其需要安装Flash插件(通常情况下,所有浏览器都会有该插件)。但是某些客户端,比如iPhone/iPad,不支持flash

    2). 其要求防火墙的843端口是打开的,这样Flash组件才能发出HTTP请求来检索包含了域授权的策略文件。如果843端口是不可到达的话,则库应该有回退动作或是给出一个错误,所有的这些处理都需要一些时间(最多3秒,这取决于库),而这会降低网站的速度。

    3). 如果客户端处在某个代理服务器的后面的话,到端口843的连接可能会被拒绝

 

WebSocket

 

简介

这是WEB通信方式的革新,基于浏览器原生socket,实现了全双工通信,使WEB上的真正的实时通信成为可能。WebSocket标准正由W3C制定,目前正处于草稿阶段,但是相信在不久的将来,它将会改变WEB实时通信方式

评价

与Ajax相比,Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。个人认为,WebSocket的缺点主要是目前客户端浏览器的支持还不够好,服务端也没有个统一标准,版本比较混乱。不过这都是处于草案期的标准必经的。相信在不久的将来情况会有改善

今天先到这里,下次给出一个demo,揭开WebSocket的神秘面纱

 

本文首发于【百度运维空间http://hi.baidu.com/ops_bd/blog/item/633b1c3eeb10d0ec3b87ce44.html

关注百度技术沙龙