ExpressJS集成express-ws实现WebSocket通信详解
作者:后端茶话时间:2026-10-30 23:33:38浏览:256
本文详解如何在ExpressJS中集成express-ws库实现WebSocket通信。内容涵盖基础用法、局部路由配置、通过Router模块化封装通道类,以及管理已连接用户状态。通过具体代码示例,展示如何混入app、定义路由及处理消息,帮助开发者快速构建实时交互应用。
版本信息
"express": "~4.16.1",
"express-ws": "^5.0.2",基础用法
- 应用配置
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 = router应用完整配置
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路由器的模块化封装方案
WebSocket模块文件
// 引入
const express = require('express');
const router = express.Router();
const expressWs = require('express-ws')通道类封装
- 实例化通道类channel,利用router定义WebSocket连接组,通过传入path参数区分路径
//类
class channel {
router;
constructor(props) {
this.router = props;
}
createChannel(path) {
// 建立通道
this.router.ws('/' + path, (ws, req) => {
ws.on('message', (msg) =>{
console.log(msg)
})
})
}
}- 方法调用示例
let channels = new channel(router)
//创建一个新的通道 路径为:/ws
channels.createChannel('ws')
//访问路径: ws://localhost:3000/ws- 监听WebSocket实例,在外部函数中接收返回参数,依据path进行逻辑区分
//类
class channel {
router;
constructor(props) {
this.router = props;
}
createChannel(path) {
// 建立通道
this.router.ws('/' + path, (ws, req) => {
ws.on('message', (msg) => getMsg(msg, path))
})
}
}
//外部函数监听客户端消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
}
}- 按路由分类存储在线用户,新增saveClients()方法
//类
class channel {
router;
clients = {
allClients: [],//存放通过当前类所创建的通道中所有已连接用户
};
constructor(props) {
this.router = props;
}
createChannel(path) {
this.clients[path] = []; //用于存放当前通道中的用户
// 建立通道
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)
}
}
// 外部函数监听客户端消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
}
}初始化函数initWebSocket
构建初始化函数,引入app并操作express-ws,将.ws方法混入app实例
调用封装的channel类以创建通信通道
//初始化
let WS = null;
// 声明一个通道类
let channels = null;
function initWebSocket(app) {
WS = expressWs(app) //混入app, wsServer 存储所有已连接实例
// 创建通道
channels = new channel(router)
channels.createChannel('ws')
//访问路径: ws://localhost:3000/ws
app.use(router)
}完整代码展示
WebSocket模块文件
//websocket.js
const express = require('express');
const router = express.Router();
const expressWs = require('express-ws')
// 初始化
let WS = null;
// 声明一个通道类
let channels = null;
function initWebSocket(app) {
WS = expressWs(app) //混入app, wsServer 存储所有已连接实例
// 创建通道
channels = new channel(router)
channels.createChannel('ws')
channels.createChannel('ws2')
app.use(router)
}
// 通道类
class channel {
router;
clients = {
allClients: [],//存放通过当前类所创建的通道中所有已连接用户
};
constructor(props) {
this.router = props;
}
createChannel(path) {
this.clients[path] = []; //用于存放当前通道中的用户
// 建立通道
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 消息内容
* @param {String} from 消息来源
*/
// 监听消息
let getMsg = (msg, from) => {
switch (from) {
case 'ws':
console.log('ws:', msg);
break;
case 'wsw':
console.log('wsw:', msg);
break;
}
SendMsgAll({ data: msg })
}
// 发送消息
let sendMsg = (client, data) => {
if (!client) return
client.send(JSON.stringify(data))
}
let close = (code) => {
console.log('关闭连接', code);
}
let error = (e) => {
console.log('error: ', e);
}
// 群发
/**
*
* @param {String} path 需要发送的用户来源 路由,默认全部
* @param {*} data 发送的数据
*/
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
}应用挂载配置
const express = require('express');
const app = express();
// WebSocket 在JWT验证之前引入挂载
const webSocket = require('./websocket')
webSocket.initWebSocket(app)
app.listen('3000')源代码
Gitee源码仓库地址:源码
本文关于ExpressJS使用express-ws的介绍至此结束,更多关于ExpressJS使用express-ws的内容请查阅本站历史文章或继续浏览后续相关文章,感谢大家的支持!
作者最新文章
Node.js中使用path模块获取文件名
2026-11-05 15:15:15
Node.js中url模块与querystring模块处理查询字符串的区别
2026-11-05 15:04:45
JavaScript(JS)主要用来做什么
2026-11-05 10:10:47
怎么修改Node.js和npm的全局安装路径与缓存目录
2026-11-04 19:48:28
NW.js 常见问题排查:Node 模块加载失败与版本兼容解决
2026-11-04 11:22:45
