|
ExpressJS集成express-ws
目录
版本
- "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
复制代码 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)
- })
- })
- 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[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.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[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
- }
复制代码 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】 我们会及时删除侵权内容,谢谢合作! |
|