WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通信的網絡技術。 WebSocket通訊協議於2011年被IETF定爲標準 RFC 6455,WebSocketAPI被W3C定爲標準。php
在WebSocket API中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。(維基百科)css
如今,不少網站爲了實現推送技術,所用的技術都是輪詢。 輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP request,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP request 的header是很是長的,裏面包含的數據可能只是一個很小的值,這樣會佔用不少的帶寬和服務器資源。html
而比較新的技術去作輪詢的效果是Comet,使用了AJAX。但這種技術雖然可達到雙向通訊,但依然須要發出請求,並且在Comet中,廣泛採用了長連接,這也會大量消耗服務器帶寬和資源。html5
面對這種情況,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬並達到實時通信。jquery
服務器與客戶端之間交換的標頭信息很小,大概只有2字節。(早期版本)web
服務器能夠主動傳送數據給客戶端。(試想一下,若是服務器在早晨會自啓動併發送數據到那些但願接收而不用提早創建一些鏈接端口的客戶端,這是一件多棒的事情啊!歡迎來到PUSH技術的世界!)chrome
下面來建立基本模板,這是個人client.php文件:瀏覽器
<!DOCTYPE html> <html> <head> <script src="js/jquery.min.js"></script> <title>WebSockets Client</title> </head> <body> <div id="wrapper"> <div id="container"> <h1>WebSockets Client</h1> <div id="chatLog"> </div><!-- #chatLog --> <p id="examples">e.g. try 'hi', 'name', 'age', 'today'</p> <input id="text" type="text" /> <button id="disconnect">Disconnect</button> </div><!-- #container --> </div> </body> </html>
咱們已經建立裏基本模板:一個chat log容器,一個input輸入框和一個斷開鏈接的按鈕。服務器
沒什麼花俏代碼,只是處理一下標籤的樣式。
websocket
body { font-family:Arial, Helvetica, sans-serif; } #container{ border:5px solid grey; width:800px; margin:0 auto; padding:10px; } #chatLog{ padding:5px; border:1px solid black; } #chatLog p { margin:0; } .event { color:#999; } .warning{ font-weight:bold; color:#CCC; }
首先讓咱們嘗試並理解WebSocket事件的概念:
WebSocket事件:
咱們將使用三個WebSocket事件:
onopen: 當接口打開時
onmessage: 當收到信息時
onclose: 當接口關閉時
咱們如何來實現呢?
首先建立WebSocket對象
//需將服務器監聽端口改成8000 var socket = new WebSocket("ws://localhost:8000/socket/server/startDaemon.php")
而後向下面這樣檢測事件
socket.onopen = function(){ alert("Socket has been opened!"); }
當咱們收到信息時這樣作:
socket.onmessage = function(msg){ alert(msg); //Awesome! }
但咱們仍是儘可能避免使用alert,如今咱們能夠把咱們學的東西整合到客戶端頁面中了。
首先咱們將代碼放到jQuery 的 document.ready函數中,而後咱們還要檢查用戶的瀏覽器是否支持WebSocket。若是不支持,咱們就添加一個鏈向Chrome瀏覽器頁面的連接。
$(document).ready(function() { if(!("WebSocket" in window)){ $('#chatLog, input, button, #examples').fadeOut("fast"); $('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container'); }else{ //The user has WebSockets connect(); function connect(){ //the connect function code is below } });
如你所見,若是用戶瀏覽器支持WebSocket,咱們將執行connect()函數。這裏是核心功能,咱們將開始建立open、close和receive事件。
咱們將在咱們的服務器定義URL。
var socket; var host = "ws://localhost:8000/socket/server/startDaemon.php";
你可能會發現URL中怎麼沒有http?恩,是的,這是一個WebSocket URL,使用了不一樣的協議。下面是URL分解圖示:
下面讓咱們繼續完成connect()函數,咱們將代碼放入try/catch塊,這樣若是代碼出現問題,咱們能讓用戶知道。咱們建立 WebSocket,並將信息傳遞到message()函數,以後會作講解。咱們建立咱們的onopen、onmessage和onclose函數. 須要注意的是咱們爲用戶提供了端口狀態,這並非必需的,但咱們把它放進來主要是爲了方便調試。
CONNECTING = 0
OPEN = 1
CLOSED = 2
function connect(){ try{ var socket; var host = "ws://localhost:8000/socket/server/startDaemon.php"; var socket = new WebSocket(host); message('<p class="event">Socket Status: '+socket.readyState); socket.onopen = function(){ message('<p class="event">Socket Status: '+socket.readyState+' (open)'); } socket.onmessage = function(msg){ message('<p class="message">Received: '+msg.data); } socket.onclose = function(){ message('<p class="event">Socket Status: '+socket.readyState+' (Closed)'); } } catch(exception){ message('<p>Error'+exception); } }
message()函數很簡單, 它將咱們想展示給用戶的文本填入chat log容器內。 咱們在socket事件函數中爲段落(<p>)標籤建立適當的class,咱們在message函數中只有一個段落結束標籤。
function message(msg){ $('#chatLog').append(msg+'</p>'); }
若是你已按上面教程循序漸進的作的話,很好,咱們已經建立了 HTML/CSS 模板、建立並創建Websocket鏈接、經過建立鏈接保持用戶的進展更新。
如今咱們已經有了提交按鈕,但咱們還須要監聽用戶按下鍵盤的事件,並運行send函數,下面的’13′即是回車鍵對應的ASCII碼。
$('#text').keypress(function(event) { if (event.keyCode == '13') { send(); } });
下面是send()函數:
function send(){ var text = $('#text').val(); if(text==""){ message('<p class="warning">Please enter a message'); return ; } try{ socket.send(text); message('<p class="event">Sent: '+text) } catch(exception){ message('<p class="warning"> Error:' + exception); } $('#text').val(""); }
下面咱們須要:
socket.send();
那些額外的代碼作了如下工做:檢測用戶是否什麼都沒輸入卻仍點擊返回、清空input輸入框、執行message()函數。
關閉Socket操做至關簡單,添加對斷開鏈接按鈕的click事件監聽就能夠。
$('#disconnect').click(function(){ socket.close(); });
$(document).ready(function() { if(!("WebSocket" in window)){ $('#chatLog, input, button, #examples').fadeOut("fast"); $('<p>Oh no, you need a browser that supports WebSockets. How about <a href="http://www.google.com/chrome">Google Chrome</a>?</p>').appendTo('#container'); }else{ //The user has WebSockets connect(); function connect(){ var socket; var host = "ws://localhost:8000/socket/server/startDaemon.php"; try{ var socket = new WebSocket(host); message('<p class="event">Socket Status: '+socket.readyState); socket.onopen = function(){ message('<p class="event">Socket Status: '+socket.readyState+' (open)'); } socket.onmessage = function(msg){ message('<p class="message">Received: '+msg.data); } socket.onclose = function(){ message('<p class="event">Socket Status: '+socket.readyState+' (Closed)'); } } catch(exception){ message('<p>Error'+exception); } function send(){ var text = $('#text').val(); if(text==""){ message('<p class="warning">Please enter a message'); return ; } try{ socket.send(text); message('<p class="event">Sent: '+text) } catch(exception){ message('<p class="warning">'); } $('#text').val(""); } function message(msg){ $('#chatLog').append(msg+'</p>'); } $('#text').keypress(function(event) { if (event.keyCode == '13') { send(); } }); $('#disconnect').click(function(){ socket.close(); }); }//End connect }//End else });