0

Hello stackoverflow community.This is my first question on this site. I spend two weeks struggling with how i can take out expressWs logic (chat window in frontend) to module and then import module in my NodeJS server file. Presently ,with this code ,i receive error "WebSocket is already in CLOSING or CLOSED state." If i write export without returning ws ,error disappears,but websocket still don't work

My current code

expressWs.js // my main server file

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 // logic of 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
})

})

  }


}
Anvar
  • 452
  • 3
  • 5

1 Answers1

0

After viewing a few eaxamples i finally wrote working module.As i understand,let aWss = expressWs.getWss('/echo') will won't work yet you wrap app by server and expressWs in same module,then export app and server. Here my working expressWs module code

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}

And import in index.js

const {app,server} = require('./websocket/expressWsModule')
Anvar
  • 452
  • 3
  • 5