【HTML5】HTML5 WebSocket簡介以及簡單示例


互聯網發展到現在,早已超越了原始的初衷,人類從來沒有像現在這樣依賴過他;也正是這種依賴,促進了互聯網技術的飛速發展。而終端設備的創新與發展,更加速了互聯網的進化;

 

HTTP/1.1規范發布於1999年,同年12月24日,HTML4.01規范發布;盡管已到2012年,但HTML4.01仍是主流;雖然 HTML5的草案已出現了好幾個年頭,但轉正日期,遙遙無期,少則三五年,多則數十年;而HTML5的客戶代理(對於一般用戶而言,就是瀏覽器),則已百 家爭鳴,星星向榮;再加上移動終端的飛速發展,在大多數情況下,我們都可以保證擁有一個HTML5的運行環境,所以,我們來分享一下HTML5中的 WebSocket協議;

本文包含以下六個方面:
1. WebSocket的前世今生
2. WebSocket是什么
3. 為什么使用WebSocket
4. WebSocket API

5. DEMO

以上六點分為兩大塊,前3點側重理論,主要讓大家明白WebSocket是什么,而后3點則結合代碼實戰,加深對WebSocket的認知。

一、WebSocket的前世今生

Web 應用的信息交互過程通常是客戶端通過瀏覽器發出一個請求,服務器端接收和審核完請求后進行處理並返回結果給客戶端,然后客戶端瀏覽器將信息呈現出來,這種 機制對於信息變化不是特別頻繁的應用尚能相安無事,但是對於那些實時要求比較高的應用來說就顯得捉襟見肘了。我們需要一種高效節能的雙向通信機制來保證數 據的實時傳輸。有web TCP之稱的WebSocket應運而生,給開發人員提供了一把強有力的武器來解決疑難雜症。
(PS:其實,在早期的HTML5規范中,並沒有包含WebSocket的定義,一些早期的HTML5書籍中,完全沒有WebSocket的介紹。直到后來,才加入到當前的草案中。)

二、WebSocket是什么?

其實,從背景介紹中,我們大致的可以猜出,WebSocket是干什么用的。前面我們提到,WebSocket有web TCP之稱,既然是TCP,肯定是用來做通信的,但是它又有不同的地方,WebSocket作為HTML5中新增的一種通信協議,由通信協議和編程API 組成,它能夠在瀏覽器和服務器之間建立雙向連接,以基於事件的方式,賦予瀏覽器原生的實時通信能力,來擴展我們的web應用,增加用戶體驗,提升應用的性 能。何謂雙向?服務器端和客戶端可以同時發送並響應請求,而不再像HTTP的請求和響應。

三、為什么使用WebSocket

在WebSocket出現之前,我們有一些其它的實時通訊方案,比較常用的有輪詢,長輪詢,流,還有基於Flash的交換數據的方式,接下來,我們一一分析一下,各種通信方式的特點。

① 輪詢
這是最早的一種實現實時web應用的方案;原理比較簡單易懂,就是客戶端以一定的時間間隔向服務器發送請求,以頻繁請求的方式來保持客戶端和服務器端的數 據同步。但是問題也很明顯:當客戶端以固定頻率向服務器端發送請求時,服務器端的數據可能並沒有更新,這樣會帶來很多無謂的請求,浪費帶寬,效率低下。

② 長輪詢
長輪詢是對定時輪詢的改進和提高,目地是為了降低無效的網絡傳輸。當服務器端沒有數據更新的時候,連接會保持一段時間周期直到數據或狀態改變或者時間過 期,通過這種機制來減少無效的客戶端和服務器間的交互。當然,如果服務端的數據變更非常頻繁的話,這種機制和定時輪詢比較起來沒有本質上的性能的提高。

③ 流
長輪詢是對定時輪詢的改進和提高,目地是為了降低無效的網絡傳輸。當服務器端沒有數據更新的時候,連接會保持一段時間周期直到數據或狀態改變或者時間過 期,通過這種機制來減少無效的客戶端和服務器間的交互。當然,如果服務端的數據變更非常頻繁的話,這種機制和定時輪詢比較起來沒有本質上的性能的提高。

④ 基於Flash的實時通訊方式
Flash有自己的socket實現,這為實時通信提供了可能。我們可以利用Flash完成數據交換,再利用Flash暴露出相應的接口,方便 JavaScript調用,來達到實時傳輸數據的目的。這種方式比前面三種方式都要高效,而且應用場景比較廣泛;因為flash本身的安裝率很高;但是在 當前的互聯網環境下,移動終端對flash的支持並不好,以IOS為主的系統中根本沒有flash的存在,而在android陣營中,雖然有flash的 支持,但實際的使用效果差強人意,即使是配置較高的移動設備,也很難讓人滿意。就在前幾天(2012年6月底),Adobe官方宣布,不在支持 android4.1以后的系統,這基本上宣告了flash在移動終端上的死亡。

下面是輪詢和長輪詢的信息流轉圖:

對比完四種不同的實時通信方式,不難發現,除了基於flash的方案外,其它三種方式都是用AJAX方式來模擬實時的效果,每次客戶端和服務器端交 互時,都是一次完整的HTTP請求和應答的過程,而每一次的HTTP請求和應答都帶有完整的HTTP頭信息,這就增加每次的數據傳輸量,而且這些方案中客 戶端和服務端的編程實現比較復雜。

接下來,我們再來看一下WebSocket,為什么要使用它呢?高效節能,簡單易用。
下圖是來自websocket.org的測試結果:

在流量和負載增大的情況下,WebSocket 方案相比傳統的 Ajax 輪詢方案有極大的性能優勢;而在開發方面,也十分簡單,我們只需要實例化WebSocket,創建連接,查看是否連接成功,然后就可以發送和相應消息了。我們會在后面的實例中去詳細的說明API。

四、WebSocket API

上面我們介紹了WebSocket服務端的知識,接下來,我們需要編寫客戶端代碼了。在前面我們說過,客戶端的API也是一如既往的簡單:

見上圖:ready state中定義的是socket的狀態,分為connection、open、closing和closed四種狀態,從字面上就可以區分出它們所代表的狀態。


上圖描述的是WebSocket的事件,分為onopen、onerror和onclose;


上圖為消息的定義,主要是接收和發送消息。注意:可以發送二進制的數據。

以上個圖的具體的含義就不再一一贅述,詳細描述請參考:
http://www.w3.org/TR/2012/WD-websockets-20120524/
PS:由於WebSocket API(截止到2012年7月)還是草案,API文檔和上文所描述的會有所不同,請以官方文檔為主,這也是我為什么不詳細描述API中各個屬性的原因。

另外一點需要提醒大家的是:在前端開發中,瀏覽器兼容是必不可少的,而WebSocket在主瀏覽器中的兼容還是不錯的,火狐和Chrome不用 說,最新版的支持非常不錯,而且支持二進制數據的發送和接收。但是IE9並不支持,對於國內的大多數應用場景,WebSocket無法大規模使用。

截圖來自(http://tongji.baidu.com/data/browser),之所以選擇百度的統計數據,是因為更加符合國內的實際情況。圖中 所展示的是2012年4月1日到2012年6月30日之間的統計數據,從圖中不難看出IE6.0、奇虎360、IE7.0和IE8.0加起來一共占據了 77%的市場,FireFox屬於其他,chrome只有5.72%的份額,再一次告訴我們,我們的主戰場依然是IE系。

既然是IE系,那么對於WebSocket在實際app中的應用就基本不可能了。但我們完全可以在chrome、FireFox、以及移動版的IOS瀏覽器中使用它。

五、DEMO

NodeJS比較簡單,所以選擇NodeJS,本身並沒有原生的WebSocket支持,但是有第三方的實現(大家要是有興趣的話,完全可以參考WebSocket協議來做自己的實現),我們選擇了“ws”作為我們的服務器端實現。

安裝ws:npm install ws

關於ws,具體查看http://einaros.github.io/ws/  簡介

DEMO有ws.html,ws.js 

ws.html源碼:

 1 <html>
 2 <head>
 3 <title>這是一個測試用例</title>
 4 </head>
 5 <body>
 6 
 7 <p id="info"></p>
 8 <p><input type="text" id="name"/></p>
 9 <p><input type="text" id="msg"/></p>
10 <p><input type="button" id="sub"/></p>
11 
12 <script type="text/javascript">
13 function $(str){
14     return document.getElementById(str);
15 }
16 var name = $('name');
17 var msg = $('msg');
18 var info = $('info');
19 var sub = $('sub');
20 var ws = new WebSocket('ws://localhost:8080/');
21 ws.onopen = function(){
22     info.innerHTML = '連接成功建立<br/>';
23 }
24 ws.onmessage = function(e){
25     info.innerHTML += e.data+'<br/>';
26 }
27 sub.onclick = function(){
28     ws.send(name.value+":"+msg.value);
29 }
30 </script>
31 </body>
32 </html>

ws.js源碼:

 1 var cons = new Array();
 2 var ws = require('ws').Server;
 3 var server = new ws({host:"localhost",port:8080});
 4 server.on('connection',function(ws){
 5   console.log('new connection founded successfully');
 6   cons.push(ws);
 7   ws.on('message',function(data){
 8     for(var i=0;i<cons.length;i++){
 9         cons[i].send(data);
10     }
11   });
12   ws.on('close',function(){
13     for(var i=0;i<cons.length;i++){
14        if(cons[i] == ws) cons.splice(i,1);
15     }
16   });
17 });
18 console.log('websocket-server running...');

麻痹,本來博客園編輯器有上傳壓縮包的,現在木有了,次奧

參考:http://ued.sina.com.cn/?p=900

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM