忍者乱太郎 发表于 2023-9-1 17:19:55

ExpressJS使用express-ws

ExpressJS集成express-ws


目录

[*]ExpressJS集成express-ws

[*]版本
[*]简单使用
[*]封装express-ws

[*]websocket.js

[*]封装通道类
[*]入口函数 initWebSocket


[*]完整代码:

[*]websocket.js
[*]app.js 挂载

[*]源码


版本

"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')封装通道类


[*]创建通道类 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 = []; //用于存放当前通道中的用户
    // 建立通道
    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.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.js

//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 = []; //用于存放当前通道中的用户
    // 建立通道
    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.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
      if (client._readyState == 1) {
            sendMsg(client, data)
      }
    }
}
module.exports = {
    initWebSocket,
    SendMsgAll
}app.js 挂载

const express = require('express');
const app = express();

// WebSocket 在JWT验证之前引入挂载
const webSocket = require('./websocket')
webSocket.initWebSocket(app)

app.listen('3000')源码

Gitee源码仓库地址:Erick-K博客源码
初步整理,功能不够全面,后续会进一步更新,欢迎评论区互相交流~

来源:https://www.cnblogs.com/tkingBlog/p/17672046.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: ExpressJS使用express-ws