WebSocket協議,是建立在TCP協議上的,而非HTTP協議。 如下: ws://127.0.0.1或wss://127.0.0.1就是WebSocket請求。 註:ws表示WebSocket協議,wss表示加密的WebSocket協議。 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