1. 程式人生 > >從web實時通訊講H5 WebSocket

從web實時通訊講H5 WebSocket

通常我們開啟一個瀏覽器訪問網頁時,都會向頁面所在的伺服器傳送一個HTTP請求,然後web伺服器確認請求並向瀏覽器做出響應。簡單的說,就是一個請求對應的一個響應。然而這種方法對許多的應用場景都會使伺服器的HTTP請求變得臃腫,甚至崩潰。比如:對於股價、新聞每日推送、好友聊天資訊收發等情況,如果每次都是客戶端傳送HTTP請求給伺服器來獲取相應資料,那麼使用者就需要每次都對頁面進行重新整理從而來獲取最新的訊息。相信這樣的網頁使用者也不會喜歡

前期實時通訊解決方式

1> HTTP輪詢 

    1.定義:輪詢是一種定時性的同步呼叫,客戶端想伺服器傳送請求檢視是否有可用的新資料。請求以固定的時間間隔發出,不管是否有資訊,客戶端都會得到響應資料:如果有可用資訊,伺服器就會將它們返回給客戶端;如果沒有可用資訊,伺服器就會返回一個拒絕響應,客戶端接受到這種響應時就可以關閉連線。輪詢的本質上就是推遲完成HTTP響應,向客戶端提交資訊

    2.適用場景:在知道資訊互動的時間間隔的情況下,使用它是一個好的辦法,然而大多數的情況下,我們都不知道資訊交付的時間間隔,我們不知道使用者什麼時候發資料,新聞什麼時候更新等等..

    3.缺陷:使用HTTP輪詢方式需要伺服器有很快處理速度和資源,而且傳送的http請求也很多

2> 長輪詢

    1.定義:客戶端向伺服器端請求資訊,並在設定的時間內開啟一個連線。伺服器如果沒有資訊推送,那麼請求就會一直開啟,知道伺服器響應資料或者設定的時間用完為止。當請求關閉時,客戶端又可以重新向伺服器傳送請求資訊。長輪詢是一種阻塞模型,類似於打電話,沒有人接就不掛電話,知道撥打電話時長超過限制或者對方接了。長輪詢也稱為Comet或者反向AJAX,長輪詢延長HTTP響應的完成時間,直到伺服器響應資料或者設定時間用完,這種技術通常稱為掛起GET或者擱置POST

    2.缺陷:當資訊量很大時,長輪詢的效能相較於傳統的通訊而言並沒有明顯的優勢,因為客戶端必須繁重得重連伺服器來獲取新資訊。並且長輪詢缺乏標準實現。而且長輪詢需要有很高的併發能力即同時接待多個客戶的能力

3> 流化技術 

    1.定義:在流化技術中,客戶端傳送一個請求,伺服器傳送並維護一個持續更新和保持開啟(可以指定時間段,也可以設定為無限)的開放響應,每當伺服器有需要交付給客戶端的資訊時,它就更新響應

    2.缺陷:流化技術中的伺服器從不發出完成HTTP響應的請求,從而使連線一直保持開啟狀態。這種情況下,代理和防火牆可能會快取HTTP響應,導致資訊交付的延遲時間增加,因此,大多數的流化測試對於存在防火牆和代理的網路都是不友好的

WebSocket

1.定義:WebSocket是一種自然的全雙工、雙向、單套接字連線。通過使用WebSocket,客戶端傳送的即時HTTP請求變成了開啟WebSocket的單一請求,並且這一請求式連線會一直重用,知道使用者關閉。

2.優勢:WebSocket明顯減少了延遲時間,因為只要建立起WebSocket連線,伺服器就可以在訊息可用時傳送他們,客戶端和伺服器連線全過程都只發出一個請求,建立一個連線,伺服器不需要等待來自客戶端的HTTP請求,同時,客戶端也可以在任何時候向伺服器傳送訊息

WebSocket與輪詢方式傳送請求的方式

WebSocket測試小例項 

// 新建js檔案 hellows.js 
<html> 
  <head> 
    <title>hello websocket</title> 
    <meta charset='UTF-8' /> 
  </head> 
  <body> 
    <input type="button" id='test' value='點我測試' /> 
    <!--引入JQuery檔案簡化DOM操作(其實就是懶~)--> 
    <script src="JS/jquery.min.js"></script> 
    <script>
            $(function(){
                //websocket測試伺服器
                var url = "ws://echo.websocket.org/echo";
                var ws = null;
                function createws(){
                    if('WebSocket' in window)
                        ws = new WebSocket(url);
                    else if('MOzWebSocket' in window)
                        ws = new MozWebSocket(url);
                    else
                        console.log("瀏覽器太舊,不支援");
                }
                function btnfun(){
                    createws();
                    //成功建立WebSocket連線時觸發onopen事件,通常客戶端傳送資料都是放在open事件裡面
                    ws.onopen = function(){
                        console.log("connected");
                        ws.send("hello world");
                    };
                    //接受伺服器響應資料時觸發onmessage事件
                    ws.onmessage = function(event){
                        console.log("receive message:"+event.data);
                        //關閉websocket連線
                        ws.close(999,"close normal");
                    };
                    //伺服器處理異常,通常在伺服器裡try-catch發生異常時或者連線異常時觸發onerror事件
                    ws.onerror = function(err){
                        console.log("error: "+err);
                        ws.close(1000,"close after error");
                    };
                    //websocket連線關閉時觸發onclose事件
                    ws.onclose = function(event){
                        console.log("close reason: "+event.reason);
                    };
                };
                //為button繫結事件
                $("#test").click($.fn.btnfun);
            });
        </script> </body> </html>

瀏覽器開啟該頁面,開啟瀏覽器的控制檯,然後點選裡面的按鈕將會出現一系列我們在裡面設定的測試輸出資料則代表websocket測試成功了。如果console控制檯輸出的是“瀏覽器太舊,不支援”,就表示當前所使用的瀏覽器版本太舊,雖然目前所有的主流瀏覽器的最新版本都包含了對WebSocket API以及其協議的支援,但是還是有一些在用的舊版本的瀏覽器沒有這方面的支援,因此想要獲得WebSocket的支援可以去下載新版本或者主流的瀏覽器,也可以研究變通或者模擬策略來自己模擬實現WebSocket~~