基于构建实时WEb应用的HTML5 WebSocket协议<二>

前面说了那么多的理论,我们来看下代码学习。

WebSocketAPI简介

首先看一段简单的javascript代码,该代码调用了WebSockets的API。
var ws = new WebSocket(“ws://echo.websocket.org”);  
ws.onopen = function(){ws.send(“Test!”); };  
ws.onmessage = function(evt){console.log(evt.data);ws.close();};  
ws.onclose = function(evt){console.log(“WebSocketClosed!”);};    
ws.onerror = function(evt){console.log(“WebSocketError!”);};
 这份代码总共只有5行,现在简单概述一下这5行代码的意义。
第一行代码是在申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,当Browser和WebSocketServer连接成功后,会触发onopen消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。

这是完整代码:

//建立 WebSocket 连接的实例 JavaScript 代码
var  wsServer = 'ws://localhost:8888/Demo'; 
var  websocket = new WebSocket(wsServer); 
websocket.onopen = function (evt) { onOpen(evt) }; 
websocket.onclose = function (evt) { onClose(evt) }; 
websocket.onmessage = function (evt) { onMessage(evt) }; 
websocket.onerror = function (evt) { onError(evt) }; 
function onOpen(evt) { 
  console.log("Connected to WebSocket server."); 
} 
function onClose(evt) { 
  console.log("Disconnected"); 
} 
function onMessage(evt) { 
  console.log('Retrieved data from server: ' + evt.data); 
} 
function onError(evt) { 
  console.log('Error occured: ' + evt.data); 
}

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

WebSocket 握手协议(客户端到服务端)
GET /demo HTTP/1.1 
Host: example.com 
Connection: Upgrade 
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 
Upgrade: WebSocket 
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5 
Origin: http://example.com 
[8-byte security key] 
服务端到客户端:
HTTP/1.1 101 WebSocket Protocol Handshake 
Upgrade: WebSocket 
Connection: Upgrade 
WebSocket-Origin: http://example.com 
WebSocket-Location: ws://example.com/demo 
[16-byte hash response]
      可以看出这些WebSocket请求和通常的 HTTP 请求很相似,但是其中有些内容是和 WebSocket 协议密切相关的。我们需要简单介绍一下这些请求和应答信息,”Upgrade:WebSocket”表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。从客户端到服务器端请求的信息里包含有”Sec-WebSocket-Key1”、“Sec-WebSocket-Key2”和”[8-byte securitykey]”这样的头信息。这是客户端浏览器需要向服务器端提供的握手信息,服务器端解析这些头信息,并在握手的过程中依据这些信息生成一个 16 位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接。一旦连接建立,客户端和服务器端就可以通过这个通道双向传输数据了(这时就是TCP传输数据了,省去了数据头数据传输)。

搭建WebSocket Server

      如果要搭建一个Web服务器,我们会有很多选择,市场上也有很多成熟的产品供我们应用,比如开源的Apache,安装后只需简单的配置(或者默认配置)就可以工作了。但是如果想搭建一个WebSocket服务器就没有那么轻松了,因为WebSocket是一种新的通信协议,目前还是草案,没有成为标准,市场上也没有成熟的WebSocket服务器或者Library实现WebSocket协议,我们就必须自己动手写代码去解析和组装WebSocket的数据包。要这样完成一个WebSocket服务器,估计所有的人都想放弃,幸好的是市场上有几款比较好的开源库供我们使用,比如PyWebSocket,WebSocket-Node,LibWebSockets等等,这些库文件已经实现了WebSocket数据包的封装和解析,我们可以调用这些接口,这在很大程度上减少了我们的工作量。
下面就简单介绍一下这些开源的库文件。
1.     PyWebSocket
PyWebSocket采用Python语言编写,可以很好的跨平台,扩展起来也比较简单,目前WebKit采用它搭建WebSocket服务器来做LayoutTest。
我们可以获取源码通过下面的命令
svncheckouthttp://pywebsocket.googlecode.com/svn/trunk/ pywebsocket-read-only
更多的详细信息可以从http://code.google.com/p/pywebsocket/获取。
2.     WebSocket-Node
WebSocket-Node采用JavaScript语言编写,这个库是建立在nodejs之上的,对于熟悉JavaScript的朋友可参考一下,另外Html5和Web应用程序受欢迎的程度越来越高,nodejs也正受到广泛的关注。
我们可以从下面的连接中获取源码
https://github.com/Worlize/Websocket-Node
3.     LibWebSockets
LibWebSockets采用C/C++语言编写,可定制化的力度更大,从TCP监听开始到封包的完成我们都可以参与编程。
我们可以从下面的命令获取源代码

git clone git://git.warmcat.com/libwebsockets

WebSocket 的局限性

       WebSocket 的优点已经列举得很多了,但是作为一个正在演变中的 Web 规范,我们也要看到目前用 Websocket 构建应用程序的一些风险。首先,WebSocket 规范目前还处于草案阶段,也就是它的规范和 API 还是有变动的可能,另外的一个风险就是微软的 IE 作为占市场份额最大的浏览器,和其他的主流浏览器相比,对 HTML5 的支持是比较差的,这是我们在构建企业级的 Web 应用的时候必须要考虑的一个问题。

总结

      因为无意看到了WebSocket协议的介绍,觉得在技术上确实是种突破,有必要学习下。尽管 HTML5 WebSocket 目前还有一些局限性,但是已经是大势所趋,微软也明确表达了未来对 HTML5 的支持,而且这些支持我们可以在 Windows 8 和 IE10 里看到,我们也在各种移动设备,平板电脑上看到了 HTML5 和 WebSocket 的身影。WebSocket 将会成为未来开发实时 Web 应用的生力军应该是毫无悬念的了,虽然不是 Web 开发人员,但关注 HTML5,关注 WebSocket 也应该提上日程了,否则我们在新一轮的软件革新的浪潮中只能做壁上观了。

学习连接:http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。