ExpressJS使用express-ws的實(shí)例詳解
版本
"express": "~4.16.1", "express-ws": "^5.0.2",
簡單使用
- app.js
const express = require('express');
const app = express();
const expressWs = require('express-ws')(app) //混入app
app.ws('/ws',(ws,req)=>{
ws.on('message',msg=>{
console.log(msg)
ws.send(msg)
})
})
app.listen('3000')- 局部路由
//websocket.js
const express = require('express');
const router = express.Router();
router.ws('/router-ws',(ws,req)=>{
ws.on('message',msg=>{
console.log(msg)
ws.send(msg)
})
})
module.exports = routerapp.js完整代碼
const express = require('express');
const app = express();
const expressWs = require('express-ws')(app) //混入app
app.ws('/ws',(ws,req)=>{
ws.on('message',msg=>{
console.log(msg)
ws.send(msg)
})
})
var webSocket = require('./websocket.js')
app.use(webSocket)
app.listen('3000')封裝express-ws
將 “express-ws” 封裝,通過 express 的 router 模塊化
websocket.js
// 引入
const express = require('express');
const router = express.Router();
const expressWs = require('express-ws')封裝通道類
- 創(chuàng)建通道類 channel,引入router定義websocket連接組,調(diào)用時(shí)傳入路徑 path 進(jìn)行區(qū)分
//類
class channel {
router;
constructor(props) {
this.router = props;
}
createChannel(path) {
// 建立通道
this.router.ws('/' + path, (ws, req) => {
ws.on('message', (msg) =>{
console.log(msg)
})
})
}
}- 調(diào)用方法
let channels = new channel(router)
//創(chuàng)建一個(gè)新的通道 路徑為:/ws
channels.createChannel('ws')
//訪問路徑: ws://localhost:3000/ws- 監(jiān)聽websocket實(shí)例,在外部函數(shù)監(jiān)聽實(shí)例返回參數(shù),并通過 path 區(qū)分
//類
class channel {
router;
constructor(props) {
this.router = props;
}
createChannel(path) {
// 建立通道
this.router.ws('/' + path, (ws, req) => {
ws.on('message', (msg) => getMsg(msg, path))
})
}
}
//外部函數(shù)監(jiān)聽客戶端消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
}
}- 根據(jù)路由分類存儲(chǔ)已連接用戶,添加 saveClients() 方法
//類
class channel {
router;
clients = {
allClients: [],//存放通過當(dāng)前類所創(chuàng)建的通道中所有已連接用戶
};
constructor(props) {
this.router = props;
}
createChannel(path) {
this.clients[path] = []; //用于存放當(dāng)前通道中的用戶
// 建立通道
this.router.ws('/' + path, (ws, req) => {
// 保存用戶
this.saveClients(ws, req, path)
ws.on('message', (msg) => getMsg(msg, path))
})
}
// 保存用戶
saveClients(socket, req, path) {
let client = {
id: req.query.id,
socket,
}
this.clients.allClients.push(client)
this.clients[path].push(client)
}
}
// 外部函數(shù)監(jiān)聽客戶端消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
}
}入口函數(shù) initWebSocket
編寫入口函數(shù),通過入口函數(shù)引入app,操作 express-ws。將 .ws 方法混入app內(nèi)
調(diào)用封裝的channel類,去創(chuàng)建通道
//初始化
let WS = null;
// 聲明一個(gè)通道類
let channels = null;
function initWebSocket(app) {
WS = expressWs(app) //混入app, wsServer 存儲(chǔ)所有已連接實(shí)例
// 創(chuàng)建通道
channels = new channel(router)
channels.createChannel('ws')
//訪問路徑: ws://localhost:3000/ws
app.use(router)
}完整代碼:
websocket.js
//websocket.js
const express = require('express');
const router = express.Router();
const expressWs = require('express-ws')
// 初始化
let WS = null;
// 聲明一個(gè)通道類
let channels = null;
function initWebSocket(app) {
WS = expressWs(app) //混入app, wsServer 存儲(chǔ)所有已連接實(shí)例
// 創(chuàng)建通道
channels = new channel(router)
channels.createChannel('ws')
channels.createChannel('ws2')
app.use(router)
}
// 通道類
class channel {
router;
clients = {
allClients: [],//存放通過當(dāng)前類所創(chuàng)建的通道中所有已連接用戶
};
constructor(props) {
this.router = props;
}
createChannel(path) {
this.clients[path] = []; //用于存放當(dāng)前通道中的用戶
// 建立通道
this.router.ws('/' + path, (ws, req) => {
// 保存用戶
this.saveClients(ws, req, path)
ws.on('message', (msg) => getMsg(msg, path))
ws.on('close', (code) => close(code, path))
ws.on('error', (e) => error(e, path))
})
}
// 保存用戶
saveClients(socket, req, path) {
let client = {
id: req.query.id,
socket,
}
this.clients.allClients.push(client)
this.clients[path].push(client)
}
}
/**
*
* @param {*} msg 消息內(nèi)容
* @param {String} from 消息來源
*/
// 監(jiān)聽消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
case 'wsw':
console.log('wsw:', msg);
break;
}
SendMsgAll({ data: msg })
}
// 發(fā)送消息
let sendMsg = (client, data) => {
if (!client) return
client.send(JSON.stringify(data))
}
let close = (code) => {
console.log('關(guān)閉連接', code);
}
let error = (e) => {
console.log('error: ', e);
}
// 群發(fā)
/**
*
* @param {String} path 需要發(fā)送的用戶來源 路由,默認(rèn)全部
* @param {*} data 發(fā)送的數(shù)據(jù)
*/
function SendMsgAll({ path = '/', data = "" }) {
let allClientsList = Array.from(WS.getWss(path).clients)
for (let key in allClientsList) {
let client = allClientsList[key]
if (client._readyState == 1) {
sendMsg(client, data)
}
}
}
module.exports = {
initWebSocket,
SendMsgAll
}app.js 掛載
const express = require('express');
const app = express();
// WebSocket 在JWT驗(yàn)證之前引入掛載
const webSocket = require('./websocket')
webSocket.initWebSocket(app)
app.listen('3000')源碼
Gitee源碼倉庫地址:源碼
到此這篇關(guān)于ExpressJS使用express-ws的文章就介紹到這了,更多相關(guān)ExpressJS使用express-ws內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
es6 super關(guān)鍵字的理解與應(yīng)用實(shí)例分析
這篇文章主要介紹了es6 super關(guān)鍵字的理解與應(yīng)用,結(jié)合實(shí)例形式分析了es6 super關(guān)鍵字的功能、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-02-02
avalon js實(shí)現(xiàn)仿google plus圖片多張拖動(dòng)排序附源碼下載
這篇文章主要介紹了avalon js實(shí)現(xiàn)仿google plus圖片多張拖動(dòng)排序附源碼下載的相關(guān)資料,需要的朋友可以參考下2015-09-09

