WebSocket简单介绍(1)

HTML5作为下一代WEB标准,拥有许多引人注目的新特性,如Canvas、本地存储、多媒体编程接口、WebSocket等等。今天我们就来看看具有“Web TCP”之称的WebSocket.

WebSocket的出现是基于Web应用的实时性需要而产生的。这种实时的Web应用大家应该不陌生,在生活中都应该用到过,比如新浪微博的评论、私信的通知腾讯的WebQQ人人网聊天在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等。让我们来回顾下实时 Web 应用的窘境吧。

在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。下面我们简单介绍一下这几种技术:

  • 轮询:这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的缺点是,当客户端以固定频率向服务 器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。
  • 长轮询:是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者 时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提 高。
  • :常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务 器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进 用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。

上述方式其实并不是真正的实时技术,只是使用了一种技巧来实现的模拟实时。在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量。但这些方式最痛苦的是开发人员,因为不论客户端还是服务器端的实现都很复杂,为了模拟比较真实的实时效果,开发人员 往往需要构造两个HTTP连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数 据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性。

基于上述弊端,实现Web实时应用的技术出现了,WebSocket通过浏览器提供的API真正实现了具备像C/S架构下的桌面系统的实时通讯能 力。其原理是使用JavaScript调用浏览器的API发出一个WebSocket请求至服务器,经过一次握手,和服务器建立了TCP通讯,因为它本质 上是一个TCP连接,所以数据传输的稳定性强和数据传输量比较小。

WebSocket 的拯救

HTML5 WebSocket 设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。因为 WebSocket 连接本质上就是一个 TCP 连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及 Comet 技术比较,具有很大的性能优势。Websocket.org 网站对传统的轮询方式和 WebSocket 调用方式作了一个详细的测试和比较,将一个简单的 Web 应用分别用轮询方式和 WebSocket 方式来实现,在这里引用一下他们的测试结果图:

通过这张图可以清楚的看出,在流量和负载增大的情况下,WebSocket 方案相比传统的 Ajax 轮询方案有极大的性能优势。这也是为什么我们认为 WebSocket 是未来实时 Web 应用的首选方案的原因。

WebSocket 协议

WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表 明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

下面我们来详细介绍一下 WebSocket 规范,由于这个规范目前还是处于草案阶段,版本的变化比较快,我们选择 draft-hixie-thewebsocketprotocol-76版本来描述 WebSocket 协议。因为这个版本目前在一些主流的浏览器上比如 Chrome,、FireFox、Opera 上都得到比较好的支持,您如果参照的是新一些的版本话,内容可能会略有差别。

一个典型的 WebSocket 发起请求和得到响应的例子看起来如下:

 

WebSocket 握手协议

 

 1 //客户端到服务端: 
 2 GET /demo HTTP/1.1 
 3 Host: example.com 
 4 Connection: Upgrade 
 5 Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 
 6 Upgrade: WebSocket 
 7 Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5 
 8 Origin: http://example.com 
 9 [8-byte security key] 
10 
11 //服务端到客户端:
12 HTTP/1.1 101 WebSocket Protocol Handshake 
13 Upgrade: WebSocket 
14 Connection: Upgrade 
15 WebSocket-Origin: http://example.com 
16 WebSocket-Location: ws://example.com/demo 
17 [16-byte hash response]

这些请求和通常的 HTTP 请求很相似,但是其中有些内容是和 WebSocket 协议密切相关的。我们需要简单介绍一下这些请求和应答信息,”Upgrade:WebSocket”表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。从客户端到服务器端请求的信息里包含有”Sec-WebSocket-Key1”、“Sec-WebSocket-Key2”和”[8-byte securitykey]”这样的头信息。这是客户端浏览器需要向服务器端提供的握手信息,服务器端解析这些头信息,并在握手的过程中依据这些信息生成一 个 16 位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接。一旦连接建立,客户端和服务器端就可以通过这个通道双向传输数据了。

在实际的开发过程中,为了使用 WebSocket 接口构建 Web 应用,我们首先需要构建一个实现了 WebSocket 规范的服务器,服务器端的实现不受平台和开发语言的限制,只需要遵从 WebSocket 规范即可,目前已经出现了一些比较成熟的 WebSocket 服务器端实现,比如:

  • Kaazing WebSocket Gateway — 一个 Java 实现的 WebSocket Server
  • mod_pywebsocket — 一个 Python 实现的 WebSocket Server
  • Netty —一个 Java 实现的网络框架其中包括了对 WebSocket 的支持
  • node.js —一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持

如果以上的 WebSocket 服务端实现还不能满足您的业务需求的话,开发人员完全可以根据 WebSocket 规范自己实现一个服务器。在“WebSocket 实战”这一节,我们将使用 Microsoft .NET 平台上的 C# 语言来打造一个简单的 WebSocket 服务器,继而构建一个简单的实时聊天系统。

posted @ 2014-08-02 23:46  SkyTeam_LBM  阅读(382)  评论(0编辑  收藏  举报