借助node實戰WebSocket


一、WebSocket概述

WebSocket協議,是建立在TCP協議上的,而非HTTP協議。

如下:

ws://127.0.0.1或wss://127.0.0.1就是WebSocket請求。

注:ws表示WebSocket協議,wss表示加密的WebSocket協議。

WebSocket的好處就是允許服務器和客服端進行實時地互相通信,而不像Ajax那樣,只能由客服端發起請求,並且WebSocket不受同源策略限制,這恰恰是Ajax的軟肋。

好了,初步了解WebSocket后,我們就一起一步步探究實現一個Demo吧。

二、客服端之旅

因為是基於WebSocket嘛,那在客服端,首先,得發起一個WebSocket請求。

如下:

<!DOCTYPE html>
    <head>
        <title>WebSocket</title>
    </head>
    <body>
        <script>
            //創建WebSocket對象請求
            var socket = new WebSocket('ws://127.0.0.1:8080/');
        </script>    
    </body>
</html>
EntireCode

其次,采用回調函數監聽相應事件,並處理。監聽事件一共四個:

  1、  onpen :請求成功時,觸發

  2、  onclose :請求關閉時,觸發

  3、  onerror :請求或連接期間出錯時,觸發

  4、  onMessage :接收服務器發送來的消息時,觸發

另,當發送請求時,創建的WebSocket 實例,有個狀態值readyState:

  1、  0 : 代表還沒連接或正在連接;

  2、  1 : 代表連接成功;

  3、  2 : 代表正在關閉連接;

  4、  3 : 代表連接關閉。

我們在該demo中加入這四個監聽事件。

如下:

<!DOCTYPE html>
    <head>
        <title>WebSocket</title>
    </head>
    <body>
        <script>
            //創建WebSocket對象請求
            var socket = new WebSocket('ws://127.0.0.1:8080/');
            //相應監聽事件
            socket.onopen = onOpen;
            socket.onclose = onClose;
            socket.onerror = onError;
            socket.onmessage = onMessage;
        </script>    
    </body>
</html>
EntireCode

在這監聽事件中,你可以按照你的意願添加觸發函數。

如下:

<!DOCTYPE html>
    <head>
        <title>WebSocket</title>
    </head>
    <body>
        <script>
            var onOpen = function(event){
                console.log('Socket opened. readyState:'+socket.readyState);
                var msg = {
                    type: "message",
                    text: "something",
                    id: "number",
                    time: Date.now()
                };
                //send可以向后台發送字符串、Blob或ArrayBuffer,固傳入對象時,利用JSON對其序列化
                socket.send(JSON.stringify(msg));
            };
            var onClose = function(event){
                console.log('Socket closed.readyState:'+socket.readyState);
                console.log('Connected to: ' + event.currentTarget.url);
            };
            var onMessage = function(data){
                console.log("We get signal:");
                console.log(data);
                console.log('onMessageready: ' + socket.readyState);
            };
            var onError = function(event){
                console.log("We got an error.: " + event.data);
            };
            var socket = new WebSocket('ws://127.0.0.1:8080/');
            socket.onopen = onOpen;
            socket.onclose = onClose;
            socket.onerror = onError;
            socket.onmessage = onMessage;
        </script>    
    </body>
</html>
EntireCode  
三、node創建服務器

借助於node創建一個簡易的服務器,以便看清整個WebSocket的流程。

因為是WebSocket協議,所以在node中你需要引入ws模塊,假設我們監聽的端口號為8080。

如下:

//需要ws模塊
var WebSocketServer = require('ws').Server;
//並創建wss服務器
var wss = new WebSocketServer({port: 8080});
EntireCode

接着,我們需要在連接成功后,我們可以向客服端發送一點點東西,如’hello world’,以及監聽客服端發送信息來時的事件message。

如下:

 

//需要ws模塊
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 8080});
wss.on('connection', function(ws){
    ws.on('message', function(message){
        var obj = JSON.parse(message);
        console.log('received: %s', obj.time);
    });
    ws.send('hello world');
});
console.log('running!!');
EntireCode
四、運行

前提:因為引入了ws模塊,所以需要引入ws模塊:npm install ws

首先,運行node搭建的簡易服務器(我將其存儲在D:WebSocket/server.js)。

如下:

 

接着,運行客服端代碼,打開chrome調試器得下:

 

再看看剛才的node環境,得下:

固,它們已經可以互相通信了。

我們再打開chrome調試器,具體看看WebSocket請求,如下:

 

在RequestHeaders,”Connection:Upgrade”表示瀏覽器通知服務器,如果可以就升級為websocket協議。Origin用於驗證瀏覽器域名是否在服務器許可范圍內。Sec-WebSocket-Key則用於握手協議密鑰,是base64編碼的16字節隨機字符串。Upgrade頭信息表示將通信協議從HTTP/1.1轉向該項所指定的協議。

在ResponseHeaders,”Connection:Upgrade”通知瀏覽器,需要改變協議。Sec-WebSocket-Accept是服務器在瀏覽器提供的Sec-WebSocket-Key字符串后面,添加“258EAFA5-E914-47DA-95CA-C5AB0DC85B11” 字符串,然后再取sha-1的hash值。瀏覽器將對這個值進行驗證,以證明確實是目標服務器回應了webSocket請求。

五、拓展閱讀

[1]  阮一峰,WebSocket

[2]  Divid Walsh,WebSocket and Socket.IO 

[3]  socket.io

[4]  Writing WebSocket client applications

[5]  WebSockets:A Guide

 


免責聲明!

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



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