翼度科技»论坛 编程开发 JavaScript 查看内容

ExpressJS使用express-ws

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
ExpressJS集成express-ws


目录

版本
  1. "express": "~4.16.1",
  2. "express-ws": "^5.0.2",
复制代码
简单使用


  • app.js
  1. const express = require('express');
  2. const app = express();
  3. const expressWs = require('express-ws')(app) //混入app
  4. app.ws('/ws',(ws,req)=>{
  5.     ws.on('message',msg=>{
  6.         console.log(msg)
  7.         ws.send(msg)
  8.     })
  9. })
  10. app.listen('3000')
复制代码

  • 局部路由
  1. //websocket.js
  2. const express = require('express');
  3. const router = express.Router();
  4. router.ws('/router-ws',(ws,req)=>{
  5.     ws.on('message',msg=>{
  6.         console.log(msg)
  7.         ws.send(msg)
  8.     })
  9. })
  10. module.exports = router
复制代码
app.js完整代码
  1. const express = require('express');
  2. const app = express();
  3. const expressWs = require('express-ws')(app) //混入app
  4. app.ws('/ws',(ws,req)=>{
  5.     ws.on('message',msg=>{
  6.         console.log(msg)
  7.         ws.send(msg)
  8.     })
  9. })
  10. var webSocket = require('./websocket.js')
  11. app.use(webSocket)
  12. app.listen('3000')
复制代码
封装express-ws

将 “express-ws” 封装,通过 express 的 router 模块化
websocket.js
  1. // 引入
  2. const express = require('express');
  3. const router = express.Router();
  4. const expressWs = require('express-ws')
复制代码
封装通道类


  • 创建通道类 channel,引入router定义websocket连接组,调用时传入路径 path 进行区分
  1. //类
  2. class channel {
  3.     router;
  4.     constructor(props) {
  5.         this.router = props;
  6.     }
  7.     createChannel(path) {
  8.         // 建立通道
  9.         this.router.ws('/' + path, (ws, req) => {
  10.             ws.on('message', (msg) =>{
  11.                 console.log(msg)
  12.             })
  13.         })
  14.     }
  15. }
复制代码

  • 调用方法
  1. let channels = new channel(router)
  2. //创建一个新的通道 路径为:/ws
  3. channels.createChannel('ws')
  4. //访问路径: ws://localhost:3000/ws
复制代码

  • 监听websocket实例,在外部函数监听实例返回参数,并通过 path 区分
  1. //类
  2. class channel {
  3.     router;
  4.     constructor(props) {
  5.         this.router = props;
  6.     }
  7.     createChannel(path) {
  8.         // 建立通道
  9.         this.router.ws('/' + path, (ws, req) => {
  10.             ws.on('message', (msg) => getMsg(msg, path))
  11.         })
  12.     }
  13. }
  14. //外部函数监听客户端消息
  15. let getMsg = (msg, from) => {
  16.     switch (from) {
  17.         case 'ws':
  18.             console.log('ws:', msg);
  19.             break;
  20.     }
  21. }
复制代码

  • 根据路由分类存储已连接用户,添加 saveClients() 方法
  1. //类
  2. class channel {
  3.     router;
  4.     clients = {
  5.         allClients: [],//存放通过当前类所创建的通道中所有已连接用户
  6.     };
  7. constructor(props) {
  8.     this.router = props;
  9. }
  10. createChannel(path) {
  11.     this.clients[path] = []; //用于存放当前通道中的用户
  12.     // 建立通道
  13.     this.router.ws('/' + path, (ws, req) => {
  14.         // 保存用户
  15.         this.saveClients(ws, req, path)
  16.         ws.on('message', (msg) => getMsg(msg, path))
  17.     })
  18. }
  19. // 保存用户
  20. saveClients(socket, req, path) {
  21.     let client = {
  22.         id: req.query.id,
  23.         socket,
  24.     }
  25.     this.clients.allClients.push(client)
  26.     this.clients[path].push(client)
  27. }
  28. }
  29. // 外部函数监听客户端消息
  30. let getMsg = (msg, from) => {
  31.     switch (from) {
  32.         case 'ws':
  33.             console.log('ws:', msg);
  34.             break;
  35.     }
  36. }
复制代码
入口函数 initWebSocket

编写入口函数,通过入口函数引入app,操作 express-ws。将 .ws 方法混入app内
调用封装的channel类,去创建通道
  1. //初始化
  2. let WS = null;
  3. // 声明一个通道类
  4. let channels = null;
  5. function initWebSocket(app) {
  6.     WS = expressWs(app) //混入app, wsServer 存储所有已连接实例
  7.     // 创建通道
  8.     channels = new channel(router)
  9.     channels.createChannel('ws')
  10.     //访问路径: ws://localhost:3000/ws
  11.     app.use(router)
  12. }
复制代码
完整代码:

websocket.js
  1. //websocket.js
  2. const express = require('express');
  3. const router = express.Router();
  4. const expressWs = require('express-ws')
  5. // 初始化
  6. let WS = null;
  7. // 声明一个通道类
  8. let channels = null;
  9. function initWebSocket(app) {
  10.     WS = expressWs(app) //混入app, wsServer 存储所有已连接实例
  11.     // 创建通道
  12.     channels = new channel(router)
  13.     channels.createChannel('ws')
  14.     channels.createChannel('ws2')
  15.     app.use(router)
  16. }
  17. // 通道类
  18. class channel {
  19.     router;
  20.     clients = {
  21.         allClients: [],//存放通过当前类所创建的通道中所有已连接用户
  22.     };
  23. constructor(props) {
  24.     this.router = props;
  25. }
  26. createChannel(path) {
  27.     this.clients[path] = []; //用于存放当前通道中的用户
  28.     // 建立通道
  29.     this.router.ws('/' + path, (ws, req) => {
  30.         // 保存用户
  31.         this.saveClients(ws, req, path)
  32.         ws.on('message', (msg) => getMsg(msg, path))
  33.         ws.on('close', (code) => close(code, path))
  34.         ws.on('error', (e) => error(e, path))
  35.     })
  36. }
  37. // 保存用户
  38. saveClients(socket, req, path) {
  39.     let client = {
  40.         id: req.query.id,
  41.         socket,
  42.     }
  43.     this.clients.allClients.push(client)
  44.     this.clients[path].push(client)
  45. }
  46. }
  47. /**
  48. *
  49. * @param {*} msg 消息内容
  50. * @param {String} from 消息来源
  51. */
  52. // 监听消息
  53. let getMsg = (msg, from) => {
  54.     switch (from) {
  55.         case 'ws':
  56.             console.log('ws:', msg);
  57.             break;
  58.         case 'wsw':
  59.             console.log('wsw:', msg);
  60.             break;
  61.     }
  62.     SendMsgAll({ data: msg })
  63. }
  64. // 发送消息
  65. let sendMsg = (client, data) => {
  66.     if (!client) return
  67.     client.send(JSON.stringify(data))
  68. }
  69. let close = (code) => {
  70.     console.log('关闭连接', code);
  71. }
  72. let error = (e) => {
  73.     console.log('error: ', e);
  74. }
  75. // 群发
  76. /**
  77. *
  78. * @param {String} path 需要发送的用户来源 路由,默认全部
  79. * @param {*} data 发送的数据
  80. */
  81. function SendMsgAll({ path = '/', data = "" }) {
  82.     let allClientsList = Array.from(WS.getWss(path).clients)
  83.     for (let key in allClientsList) {
  84.         let client = allClientsList[key]
  85.         if (client._readyState == 1) {
  86.             sendMsg(client, data)
  87.         }
  88.     }
  89. }
  90. module.exports = {
  91.     initWebSocket,
  92.     SendMsgAll
  93. }
复制代码
app.js 挂载
  1. const express = require('express');
  2. const app = express();
  3. // WebSocket 在JWT验证之前引入挂载
  4. const webSocket = require('./websocket')
  5. webSocket.initWebSocket(app)
  6. app.listen('3000')
复制代码
源码

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

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

举报 回复 使用道具