WebSocket分析及实践

作者:黄 晓安, 何 亮, 和 许 宁来源:https://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/WebSocket产生背景:实时Web应用的窘境
应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说实时报表统计、在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了 。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题 。
在 WebSocket 出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术 。下面简单介绍一下这几种技术:
轮询
这是最早的一种实现实时 Web 应用的方案 。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步 。这种同步方案的最大问题是:当客户端以固定频率向服务器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案 。
长轮询:
长轮询是对定时轮询的改进和提高,目地是为了降低无效的网络传输 。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者时间过期,通过这种机制来减少无效的客户端和服务器间的交互 。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高 。
流:
流技术方案通常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求 。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务器端的连接不过期 。通过这种机制可以将服务器端的信息源源不断地推向客户端 。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验 。
综合这几种方案,您会发现这些目前我们所使用的所谓的实时技术并不是真正的实时技术,它们只是在用 Ajax 方式来模拟实时的效果,在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量,而且这些方案中客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性 。
##什么是WebSocket?
WebSocket是html5的新特性之一,其设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力 。
那WebSocket究竟是什么?首先我们需要清楚,WebSocket本质上就是一种计算机网络应用层的协议(HTTP就是一种网络应用层协议),用来弥补HTTP协议在持久通信能力上的不足 。我们知道HTTP协议本身是无状态协议,每一个新的HTTP请求,只能通过客户端主动发起,通过建立连接-->传输数据-->断开连接的方式来传输数据,传送完连接就断开了,也就是此次HTTP请求已经完全结束了(虽然HTTP1.1增加了keep-alive请求头可以通过一条通道请求多次,但本质上还是一样的) 。并且服务器是不能主动给客户端发送数据的(因为之前的请求得到响应后连接就断开了,之后服务器根本不知道谁请求过),客户端也不会知道之前请求的任何信息,所以HTTP协议本身是没有持久通信能力的,正因为这样,也就出现了上述实时Web应用的窘境 。
WebSocket协议实现了浏览器与服务器的全双工通信(指在通信的任意时刻,线路上存在A到B和B到A的双向信号传输,简单说就如同打电话一样,浏览器和服务器任何一方随时都能够主动给对方说话) 。并且在HTML5标准中增加了有关WebSocket协议的相关API,所以只要实现了HTML5标准的客户端,就可以与支持WebSocket协议的服务器进行全双工的持久通信了 。


推荐阅读