首页 > 解决方案 > 如何正确取出 NodeJs 中 expressWs 模块的逻辑?

问题描述

你好 stackoverflow 社区。这是我在这个网站上的第一个问题。我花了两周时间努力研究如何将 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
})

})

  }


}

标签: node.jswebsocketwsexpress-ws

解决方案


在查看了一些示例后,我终于编写了工作模块。据我所知,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')

推荐阅读