如何正确取出 NodeJs 中 expressWs 模块的逻辑?

Posted

技术标签:

【中文标题】如何正确取出 NodeJs 中 expressWs 模块的逻辑?【英文标题】:How properly take out logic of expressWs module in NodeJs? 【发布时间】:2021-10-29 13:39:25 【问题描述】:

你好 *** 社区。这是我在这个网站上的第一个问题。 我花了两周时间努力研究如何将 expressWs 逻辑(前端的聊天窗口)取出到模块中,然后在我的 NodeJS 服务器文件中导入模块。 目前,使用此代码,我收到错误“WebSocket 已处于 CLOSING 或 CLOSED 状态。” 如果我写导出而不返回ws,错误消失,但websocket仍然不起作用

我当前的代码

expressWs.js // 我的主服务器文件

require('dotenv').config() 
const sequelize = require("./db")
const fileUpload = require("express-fileupload")
const cors  = require("cors")
const router = require("./routes/index")
const errorHandler = require("./middleware/ErrorHandlingMiddleware")
const path = require("path")
const fs = require('fs')
const websocketController = require('./websocket/websocketController')
const expressWsModule = require('./websocket/expressWsModule')
var express = require('express');
var expressWs = require('express-ws');
const  send  = require('process')
var expressWs = expressWs(express());
var app = expressWs.app;

app.use(express.static('public'));

var aWss = expressWs.getWss('/');
const PORT = process.env.PORT

app.use(cors(
  origin: '*'
))
app.use(express.json())
app.use(fileUpload())
app.use(express.static(path.resolve(__dirname, "static")))
app.use('/api',router)
app.use(errorHandler)

let history = []
let clients = []
let currentClient

app.ws('',websocketController(app))


const start = async () => 
    try 
        await sequelize.authenticate()
        await sequelize.sync()
        // app.listen(PORT,() => console.log(`Server started on port $PORT`) )
        // server.listen(PORT)
        app.listen(PORT);
     catch (e)
        console.log(e)
    


start()

websocketController.js // expressWs的逻辑

module.exports = function websocketController(app)
  
  return function (ws)
  

  console.log('ws module')
  let history = []
  let clients = []
  let currentClient

app.ws('/echo', (ws, req) =>
  var aWss = app.getWss('/echo')

  console.log('Socket Connected');
  ws.send(JSON.stringify(history))
  console.log('history',history)
  


  ws.on('message', msg => 

    msg = JSON.parse(msg)
    currentClient =  msg.username.slice()
    
    if(msg.event === 'message')
      history.push(msg)
      history.slice(-100)
    
    if(msg.event === 'connection')
      clients.push(currentClient)
    
    console.log('clients',clients)
    
    aWss.clients.forEach(client => 
      // client.send(msg)
      client.send(JSON.stringify(msg))
      console.log('msg',msg)
  )
    
)



ws.on('close', () => 
    console.log('WebSocket was closed')
    console.log('currentClient',currentClient)
    console.log('clients after filter',clients)
    clients.splice(clients.indexOf(currentClient),1)
    currentClient = undefined
)

)

  



【问题讨论】:

【参考方案1】:

在查看了一些示例后,我终于编写了工作模块。据我了解,let aWss = expressWs.getWss('/echo') 将无法工作,但您将应用程序通过服务器和 expressWs 包装在同一模块中,然后导出应用程序和服务器。 这是我的工作 expressWs 模块代码

require('dotenv').config() 
const path = require("path")
const fs = require('fs')
var express = require('express');
const app = express()
var server = require('http').Server(app);
var expressWs = require('express-ws')(app,server);

let history = []
let clients = []
let currentClient

let aWss = expressWs.getWss('/echo');
// console.log('in main',aWss)

app.ws('/echo', (ws, req) =>
  
  console.log('Socket Connected');
  // ws.send(history)
  ws.send(JSON.stringify(history))
  // currentClient = aWss.clients
  // clients.push(currentClient)
  console.log('history',history)
  


  //   function broadcastMessage(message) 
  //     aWss.clients.forEach(client => 
  //         client.send(JSON.stringify(message))
  //     )
  // 
  ws.on('message', msg => 
    // ws.send(msg)
    msg = JSON.parse(msg)
    currentClient =  msg.username.slice()
    
    if(msg.event === 'message')
      history.push(msg)
      history.slice(-100)
    
    if(msg.event === 'connection')
      clients.push(currentClient)
    
    console.log('clients',clients)
    
    aWss.clients.forEach(client => 
      // client.send(msg)
      client.send(JSON.stringify(msg))
      console.log('msg',msg)
  )
    
)



ws.on('close', () => 
    console.log('WebSocket was closed')
    console.log('currentClient',currentClient)
    console.log('clients after filter',clients)
    clients.splice(clients.indexOf(currentClient),1)
    currentClient = undefined
)

)

module.exports = app: app,server: server

并在 index.js 中导入

const app,server = require('./websocket/expressWsModule')

【讨论】:

以上是关于如何正确取出 NodeJs 中 expressWs 模块的逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

如何以正确的方式将 PostgreSQL 连接到 NodeJS? [复制]

如何使用猫鼬正确塑造发送到 NodeJS 服务器的搜索日期

nodejs操作mysql取出来的datatime与实际差8小时问题

NodeJS RESTful API - 如何正确处理“未定义”请求变量?

NodeJS/Typescript 导出/导入的正确解释?

如何创建从 nodejs mysql 模块获取的正确 json 类型数据?