ws模塊是Node端的一個WebSocket協議的實現,該協議容許客戶端(通常是瀏覽器)持久化和服務端的鏈接.html
這種能夠持續鏈接的特性使得WebScoket特別適合用於適合用於遊戲或者聊天室等使用場景.git
ws模塊相較於其餘基於WebSocket協議的模塊來講很是的純粹.
他只關注基於WebSocket協議的實現,其餘例如Socket.io
提供了回退手段,當WebSocket沒法使用的時候會利用輪詢來模擬持久化鏈接.github
WebSocket協議被設計的十分簡單且有效,沒有了解過的朋友能夠先了解一下,這裏附上幾個介紹WebSocket協議的文章.web
https://developer.mozilla.org...
http://www.ruanyifeng.com/blo...
https://www.cnblogs.com/fuqia...
本文章主要分爲以下幾個部分:npm
本文章中使用的ws版本爲6.1.0
.瀏覽器
ws模塊基本分爲兩個部分,有着以下的特色:服務器
server部分websocket
client部分app
引入ws模塊:socket
const WebSocket = require('ws');
建立服務器:
const wss = new WebSocket.Server({ port:8080 });
建立客戶端:
const ws = new WebSocket('ws://127.0.0.1:8080');
ws服務器的創建能夠基於一個Http服務器或者使用內部的Http服務器,爲了簡單介紹後面的例子一概使用內部服務器.
ws模塊的服務端的建立和使用很是相似於Node的Http模塊:
const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); // 監聽端口 wss.on('connection', function connection(ws) { // 當服務器和客戶端握手成功後觸發該事件,而第一個參數就是一個client對象 ws.on('message', function incoming(message) { console.log('客戶端發送的數據', message); }); ws.send('something'); // 響應內容 });
這裏須要指明的一點是,WebSocket是經過Http進行協議升級後爲WebSocket協議的.
在connection
事件中第一個參數爲一個Client對象實際上就是ws模塊的客戶端實例.
ws模塊用這個對象來描述一個鏈接對象.
而第二個參數是一個http.IncomingMessage
對象,能夠利用他來獲取請求參數例如Cookie
.
這裏你們只要記住connection
事件的第一個參數是一個ws
實例對象就能夠了,後面會介紹這個對象.
Server端有不少事件和屬性還有方法,這裏我只寫出了一些常見的參數,詳細的官方文檔我會添加在文章的末尾.
事件:
屬性:
方法:
上文中已經提到了ws模塊提供的客戶端API幾乎和瀏覽器一致,確實如此,可是它提供了比瀏覽器端更加豐富的功能.
例子使用客戶端(該例子來源於官網):
const WebSocket = require('ws'); const ws = new WebSocket('wss://echo.websocket.org/', { origin: 'https://websocket.org' }); ws.on('open', function open() { // 握手成功後觸發 console.log('connected'); ws.send(Date.now()); }); ws.on('close', function close() { console.log('disconnected'); }); ws.on('message', function incoming(data) { // 服務器信息到達時候觸發 console.log(`Roundtrip time: ${Date.now() - data} ms`); setTimeout(function timeout() { ws.send(Date.now()); }, 500); });
echo.websocket.org
這個網站中提供了一個簡單的webSocket的服務器,你能夠直接在Node中運行上面這個例子.
一樣的客戶端也提供了豐富的事件屬性和方法,這裏簡單的介紹了一些最常使用的內容:
事件
方法
屬性
const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('服務器接受到客戶端傳送的內容:', message); }); // 服務器發送的數據 ws.send('這是服務器發送的數據'); }); const ws = new WebSocket('ws://127.0.0.1:8080'); ws.on('open', function open() { // 客戶端發送的數據 ws.send('我是客戶端'); }); ws.on('message', function incoming(data) { // 接受到服務端發送的數據 console.log('客戶端接受到服務器的內容',data); });
輸出:
客戶端接受到服務器的內容 這是服務器發送的數據 服務器接受到客戶端傳送的內容: 我是客戶端
廣播消息的基本原理就是獲取服務器在connection
事件中傳入的client對象,而後client對象都收集起來,而後迭代調用send
方法.
官方的例子:
const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); // 給服務器對象上掛載一個廣播的方法,向全部人廣播 wss.broadcast = function broadcast(data) { // 獲取服務器全部的鏈接而後迭代 wss.clients.forEach(function each(client) { // 若是鏈接是打開狀態 if (client.readyState === WebSocket.OPEN) { // 發送消息 client.send(data); } }); }; wss.on('connection', function connection(ws) { ws.on('message', function incoming(data) { // 迭代服務器中的全部的客戶端對象 wss.clients.forEach(function each(client) { // 若是鏈接狀態是打開狀態,且不是當前客戶端對象 if (client !== ws && client.readyState === WebSocket.OPEN) { // 發送消息 client.send(data); } }); }); });
服務器:
const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('服務器接受到客戶端傳送的內容:', message); }); // 服務器發送的數據 ws.send('這是服務器發送的數據'); });
瀏覽器:
const client = new WebSocket('ws://127.0.0.1:8080'); client.addEventListener('open',()=>{ // 客戶端發送的數據 client.send('我是客戶端'); }); client.addEventListener('message',(data)=>{ // 接受到服務端發送的數據 console.log('客戶端接受到服務器的內容', data); });
特性 | 瀏覽器 | ws客戶端 |
---|---|---|
使用on方法添加事件 | 不能夠 | 能夠 |
使用addEventListener | 能夠 | 能夠 |
使用onerror,onclose... | 能夠 | 能夠 |
message事件,evnt.data獲取數據 | 是 | 否 |
readyState屬性 | 是 | 是 |
代碼已放到github:
https://github.com/uioz/Simpl...
注意:沒有使用構建工具.
注意:該項目服務器部分是使用TS編寫的,可是客戶端沒有使用TS.
npm指引包含:
https://www.npmjs.com/package/ws
API手冊:
https://github.com/websockets...