0

I am using 'fastify-ws' for WebSocket in node.js application. I am using HTTP communication also in the same port. I have to send the HTTP responses through the WebSocket to the connected sockets.

This is my sample code:

var connectedSockets = [];

function socketConnect(socket, req) {
  console.log('Client connected');
  connectedSockets.push(socket);

  socket.on('close', () => {
    console.log('websocket closed');
    connectedSockets = connectedSockets.filter((sk) => sk !== socket);
    });
}

module.exports = { connectedSockets, socketConnect };

If any client is connected, I will push the socket into the connectedSockets array and on close, I will remove the particular socket from the array. Then I will send the HTTP responses as follows through WebSockets in another file.

const { connectedSockets } = require('../controllers');

// inside response

connectedSockets.forEach((socket) => {
            socket.send(JSON.stringify(response));
        });

By doing this, the client can be connected. I can send the responses successfully. If multiple clients are connected and one client is closed, it throws an error like 'WebSocket is not open readystate 3 (CLOSED)' while sending the response. The problem is the disconnected socket object is still in the connectedSockets array and it has a property _closedFrameReceived: true.

Alex Isaac
  • 41
  • 1
  • 5

1 Answers1

0

The problem with your script is that you have 2 files:

  • File A with connectedSockets that point to an array

  • File B with connectedSockets that point to the connectedSockets of File A

When you do

connectedSockets = connectedSockets.filter((sk) => sk !== socket);

you are changing only the pointer of connectedSockets of File A and File B pointer is not updated and it links the old array.

You should change the array like this:

const index = connectedSockets.findIndex((sk) => sk === socket);
if (index > -1) {
  connectedSockets.splice(index, 1);
}

Or update the var in File B.

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73