I am delighted that the application I built with Next.js and NestJS is now online and operational. However, it is not performing as I had anticipated. Given that it is a real-time application, I expected it to utilize websockets. Instead, it is resorting to using the fallback method of HTTP pooling.

I have exhaustively attempted various solutions from GitHub and Stack Overflow to address this persistent error:

WebSocket connection to 'wss://api.ipm.poker/socket.io/?roomId=1&EIO=4&transport=websocket&sid=dBiHvw6rmlj2U4V3AAAI' failed: 

In Firefox, the error message is:or in Firefox you will see:

Firefox can’t establish a connection to the server at wss://api.ipm.poker/socket.io/?roomId=1&EIO=4&transport=websocket&sid=Vdy3c9KkYXyfDFFhAAAK.

Furthermore, Firefox presents additional errors such as NS_ERROR_WEBSOCKET_CONNECTION_REFUSED and 400 Bad Request.

Initially, I suspected a credential issue. However, after hours of thorough debugging, I could not pinpoint any problems related to credentials. My next hypothesis was centered around CORS origin, a commonly discussed topic on both Stack Overflow and SocketIO forums.

Surprisingly, CORS does not seem to be the culprit, even though I have allowed access from all domains.

To gain more insight, I added extensive logging from the front-end to the server. Strangely, all indications suggested a successful connection:

socket.on('connect', () => {
  const transport = socket.io.engine.transport.name
  console.info('transport', transport)
  console.info('connect', 'connected')

  socket.io.engine.on('upgrade', () => {
    const upgradeTransport = socket.io.engine.transport.name
    console.log('upgradeTransport', upgradeTransport)
  })
})
socket.on('disconnect', () => {
  console.info('disconnect', 'disconnect')
})
socket.on('connect_error', (err) => {
  console.error('connect_error', err)
})
socket.on('error', (err) => {
  console.error('error', err)
})
socket.on('reconnect_error', (err) => {
  console.error('reconnect_error', err)
})
socket.on('reconnect_failed', (err) => {
  console.error('reconnect_failed', err)
})

Curiously, even though the server logs indicated a successful connection, the issue persisted.

After extensive and lengthy debugging efforts, I finally identified the root cause of the problem: the error originated from the proxy server, specifically, Nginx. By default, Nginx does not initiate an upgrade to the connection when a protocol switch occurs.

Before making the necessary adjustments, my configuration looked like this:

location / {
    proxy_pass http://127.0.0.1:5000;
    include proxy_params;
}

In order to resolve this issue, the following lines should be added to the configuration:And you should add:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Therefore, the updated configuration should appear as follows:So it looks like this:

location / {
    proxy_pass http://127.0.0.1:5000;
    include proxy_params;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

This solution was sourced from the following references: :