嚴格地說,WebSocket技術不屬於HTML5,這個技術是對HTTP無狀態連接的一種革新,本質就是一種持久性socket連接,在瀏覽器客戶端通過javascript進行初始化連接后,就可以監聽相關的事件和調用socket方法來對服務器的消息進行讀寫操作。與Ajax相比,Ajax技術需要客戶端發起請求,而WebSocket服務器和客戶端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允許跨域通信,這個特性導致我們至少可以用來做遠控。
WebSocket實現了全雙工通信,使WEB上的真正的實時通信成為可能。瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。在WebSocket協議中,為我們實現即時服務帶來了三個好處:
- 客戶端和服務器端之間數據傳輸時請求頭信息比較小,大概2個字節。
- 服務器和客戶端可以相互主動的發送數據給對方。
- 不需要多次創建TCP請求和銷毀,節約寬帶和服務器的資源。
WebSocket的官方地址是:www.websocket.org,其中給出了一些樣例,可以直接在線測試。
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>