websocket協議及案例


WebSocket是一種用於在服務器與客戶端之間實現高效的雙向通信的機制。可以解決數據實時性要求比較高的應用,比如:在線聊天,在線教育,炒股或定位等。

一:websocket產生背景:

為了解決這種實時性的問題,有幾種替代方案:

1、輪詢

概念:客戶端通過一定的時間間隔以頻繁請求的方式向服務器發送請求,來保持客戶端和服務器端的數據同步;

缺點:當客戶端以固定頻率向服務器端發送請求時,服務器端的數據可能並沒有更新,帶來很多無謂請求,浪費帶寬,效率低下

2、Comet技術(長輪詢)

概念:長輪詢在客戶端發送請求后,服務器保留響應,並維持連接,可以在任意時間點從服務器返回響應。而客戶端在收到響應的同時再次向服務器建立連接。實例:WebQQ

缺點:與輪詢相比,長輪詢避免了不必要的通信過程,但也需要在有更新時再次連接

3、Comet技術(流技術)

概念:通過由客戶端發出第一個請求,建立連接,並在維持該連接的同時從服務器不斷向客戶端返回響應

缺點:服務器維護一個長連接會增加開銷

 

傳統實時性技術的通信數據流如下圖:

 

二:websocket的運行機制

1、WebSocket只有在建立握手連接的時候借用了HTTP協議的頭,連接成功后的通信部分都是基於TCP的連接,它與 HTTP 之間的唯一關系就是它的握手請求可以作為一個升級請求(Upgrade request)經由 HTTP 服務器解釋

 

2、WebSocket 請求響應客戶端服務器交互圖

只經過一次握手即可進行雙向通信。

 

3、WebSocket 協議優點:

1. Header
互相溝通的Header是很小的-大概只有 2 Bytes

2. Server Push
服務器的推送,服務器不再被動的接收到瀏覽器的請求之后才返回數據,而是在有新數據時就主動推送給瀏覽器

 

4.websocket的api

websocket中有兩個方法:
1、send() 向遠程服務器發送數據
2、close() 關閉該websocket鏈接

websocket同時還定義了幾個監聽函數
1、onopen 當網絡連接建立時觸發該事件
2、onerror 當網絡發生錯誤時觸發該事件
3、onclose 當websocket被關閉時觸發該事件
4、onmessage 當websocket接收到服務器發來的消息的時觸發的事件,也是通信中最重要的一個監聽事件。


5、websocket還定義了一個readyState屬性:    
1、CONNECTING(0) websocket正嘗試與服務器建立連接    
2、OPEN(1) websocket與服務器已經建立連接    
3、CLOSING(2) websocket正在關閉與服務器的連接    
4、CLOSED(3) websocket已經關閉了與服務器的連接

 

簡單的客戶端與服務器通信的案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webSocket示例</title>
</head>
<body>
    <h1>Echo Test</h1>
    <input id="sendTxt" type="text" />
    <button id="sendBtn">發送</button>
    <div id="recv"></div>
    <script>
        //創建websocket實例
        var websocket=new WebSocket('ws://echo.websocket.org');  //‘ws://echo.websocket.org’是websocket測試的服務器,把你的數據原封不動的返回給你
        //建立連接后的事件
        websocket.onopen=function(){
            console.log('websocket open');
            document.getElementById('recv').innerHTML='Connected';
        }
        //關閉連接
        websocket.onclose==function(){
            console.log('websocket close');
        }
        //客戶端接收到數據觸發
        websocket.onmessage=function(e){
            console.log(e.data);
            document.getElementById('recv').innerHTML=e.data;
        }
        //點擊發送按鈕觸發
        document.getElementById('sendBtn').onclick=function(){
            var txt=document.getElementById('sendTxt').value;
            document.getElementById('recv').innerHTML=txt;
        }
    </script>
</body>
</html>

直接瀏覽器打開文件,即可運行。

按F12觀察一下

協議是ws協議,且狀態是101正在連接的狀態。

 

四、下面是制作一個簡單聊天室功能

需要nodejs作服務器后台

package.json文件(下載nodejs-websocket模塊)

{
  "name": "demo2",
  "version": "1.0.0",
  "description": "",
  "main": "wsServer.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "nodejs-websocket": "^1.7.1"
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webSocket示例</title>
</head>
<body>
    <h1>Echo Test</h1>
    <input id="sendTxt" type="text" />
    <button id="sendBtn">發送</button>
    <div id="recv"></div>
    <script>
        var websocket=new WebSocket('ws://localhost:8001/'); 
        function showMessage(str){
            var div=document.createElement('div');
            div.innerHTML=str;
            document.body.appendChild(div);
        }
        //建立連接
        websocket.onopen=function(){
            console.log('websocket open');
            document.getElementById('sendBtn').onclick=function(){
                var txt=document.getElementById('sendTxt').value;
                if(txt){
                    websocket.send(txt);  //發送數據給服務器
                }
            }
        }
        //關閉連接
        websocket.onclose==function(){
            console.log('websocket close');
        }
        //客戶端接收數據觸發
        websocket.onmessage=function(e){
            console.log(e.data);
            showMessage(e.data);
        }
    </script>
</body>
</html>

wsServer.js

var ws = require("nodejs-websocket");
 
var clientCount=0;

var server = ws.createServer(function (conn) {
    console.log("New connection")
    clientCount++;
    conn.nickname='user'+clientCount;
    boradcast(conn.nickname+' comes in');
    //服務端接收到消息后觸發
    conn.on("text", function (str) {
        boradcast(conn.nickname+' says: '+str);
    })
    //關閉連接
    conn.on("close", function (code, reason) {
        console.log("Connection closed");
        boradcast(conn.nickname+' left');
    })
    //
    conn.on("error",function(err){
        console.log("handle err");
        console.log(err);
    })
}).listen(8001);

function boradcast(str){
    server.connections.forEach(function(connection){
        connection.sendText(str);
    })
}

運行node wsServer.js

運行node之后,直接打開瀏覽器瀏覽文件,一個文件代表一個用戶,這樣就可以兩邊對話了。

這個h5的新協議還是很有趣的。

推薦去看一下:http://www.imooc.com/learn/861   websocket案例講解。


免責聲明!

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



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