严格地说,WebSocket技术不属于HTML5,这个技术是对HTTP无状态连接的一种革新,本质就是一种持久性socket连接,在浏览器客户端通过javascript进行初始化连接后,就可以监听相关的事件和调用socket方法来对服务器的消息进行读写操作。与Ajax相比,Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信,这个特性导致我们至少可以用来做远控。
WebSocket实现了全双工通信,使WEB上的真正的实时通信成为可能。浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在WebSocket协议中,为我们实现即时服务带来了三个好处:
- 客户端和服务器端之间数据传输时请求头信息比较小,大概2个字节。
- 服务器和客户端可以相互主动的发送数据给对方。
- 不需要多次创建TCP请求和销毁,节约宽带和服务器的资源。
WebSocket的官方地址是:www.websocket.org,其中给出了一些样例,可以直接在线测试。
对于WebSocket,目前浏览器支持情况如下:
Chrome
|
Supported in version 4+
|
Firefox
|
Supported in version 4+
|
Internet Explorer
|
Supported in version 10+
|
Opera
|
Supported in version 10+
|
Safari
|
Supported in version 5+
|
服务器支持情况如下:
服务器名称 | 下载网址 |
Tomcat服务器 | http://tomcat.apache.org |
Php服务器 | http://code.google.com/p/phpwebsocket |
Node服务器 | http://nodejs.org |
Ruby服务器 | http://github.com/gimite/web-socket-ruby |
Jetty服务器 | http://jetty.codehaus.org/jetty/ |
Netty服务器 | http://www.jboss.org/netty |
Kaazing服务器 | http://www.kaazizng.org/confluence/KAAZING/Home |
这里选择Node服务器,创建WebSocket Node.js应用程序事实上的标准库Socket.IO。node.js提供了高效的服务端运行环境,socket.io基于node.js并简化了WebSocket API,统一了通信的API,统一了服务端与客户端的编程方式。
与很多其他的Node.js库相似,Socket.IO也是一个NPM模块,可以按如下方式进行安装:
$ npm install socket.io
下面是一个基于Socket.IO的WebSocket聊天应用程序
Node.js服务器端代码server.js:
var io = require('socket.io').listen(4000); io.sockets.on('connection', function (socket) { socket.on('clientMessage', function(content) { socket.emit('serverMessage', 'You said: ' + content); socket.broadcast.emit('serverMessage', socket.id + ' said: ' + content); }); });
客户端代码client.html:
<html> <head> <title>Node.js WebSocket chat</title> <style type="text/css"> #input { width: 200px; } #messages { position: fixed; top: 40px; bottom: 8px; left: 8px; right: 8px; border: 1px solid #EEEEEE; padding: 8px; } </style> </head> <body> Your message: <input type="text" id="input"> <div id="messages"></div> <script src="http://localhost:4000/socket.io/socket.io.js"></script> <script type="text/javascript"> var messagesElement = document.getElementById('messages'); var lastMessageElement = null; function addMessage(message) { var newMessageElement = document.createElement('div'); var newMessageText = document.createTextNode(message); newMessageElement.appendChild(newMessageText); messagesElement.insertBefore(newMessageElement, lastMessageElement); lastMessageElement = newMessageElement; } var socket = io.connect('http://localhost:4000'); socket.on('serverMessage', function(content) { addMessage(content); }); var inputElement = document.getElementById('input'); inputElement.onkeydown = function(keyboardEvent) { if (keyboardEvent.keyCode === 13) { socket.emit('clientMessage', inputElement.value); inputElement.value = ''; return false; } else { return true; } }; </script> </body> </html>