17

I use socket.io in my node.js app that's running on express.

Everything words fine on the local version (localhost) however when I switch to my production server (which is served via https using a custom certificate), I get the following error in my browser console:

websocket.js:112 WebSocket connection to 'wss://infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP' failed: Error during WebSocket handshake: Unexpected response code: 400

I made a research (issue referenced here) and it turns out this happens because my app / hosting provider blocks connections like wss and my socket.io falls back on AJAX to make requests (which functions OK, but sometimes there are bugs).

So I wanted to ask you if I could do modifications to my app to get rid of this error?

Just FYI currently all requests to http://infranodus.com are forwarded (via static .htaccess) to https://infranodus.com and my app.js file (the part of the server activation looks like that):

var http = require('http');

var app = express();

var server = http.Server(app);
var io = require('socket.io')(server);

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

and the way I require sockets in my front-end file:

<script src="/socket.io/socket.io.js"></script>

and then

var socket = io();

Maybe the problem is that I activate server in my node.js app using http and not https? But I would not like to switch to that because I don't know where my certificates are stored and I would not like to change the backend code too much.

UPDATE (21/10/2018): We figured out the problem is with nginx server and due to the limitations of some hosting providers who do not allow users to edit nginx servers, websockets over secure protocol get blocked or get 400 error. It would be nice to resolve this in sockets.io as it's a problem that many users have. Any ideas?

TO REPRODUCE THE ISSUE: Please, go open your Javascript Console and go to https://infranodus.com/news/english

SOURCE CODE: https://github.com/noduslabs/infranodus

10 Rep
  • 2,217
  • 7
  • 19
  • 33
Aerodynamika
  • 7,883
  • 16
  • 78
  • 137

6 Answers6

6

I solved it with this:

var socket = io.connect("http://localhost:3000", {
   forceNew: true,
   transports: ["polling"],
});
Maxdola
  • 1,562
  • 2
  • 10
  • 29
Paris López
  • 57
  • 1
  • 1
4

Check if you using express-status-monitor as a middleware on express, this makes http call on the first (request) handshake of WebSocket goes failed, if not maybe another factor like proxy (nginx) or similar like that

Look here More details about this error

Aditya Kresna Permana
  • 11,869
  • 8
  • 42
  • 48
  • Oh yes, I was all over that page, but no help there. And yes, it's a nginx issue and if I had access to my nginx server I could sort this out but how to resolve it when I don't have access? I develop this code so people can also install it on other servers and not all servers have the capacity to go to that level of config, so what to do? – Aerodynamika Oct 21 '18 at 21:53
  • When I face this problem try to break down every middleware attached into express, then do checking if the handshake issue was resolved by dropping them one by one. At the first place you should check that your application is not the issue. – Aditya Kresna Permana Oct 24 '18 at 03:47
2

Use a secure URL for your initial connection, i.e. instead of "http://" use "https://". If the WebSocket transport is chosen, then Socket.IO should automatically use "wss://" (SSL) for the WebSocket connection too.

If you are not specifying any URL when you call io(), since it defaults trying to connect to the host that serves the page, either you have to provide url or change to https

  var socket = io.connect('https://localhost', {secure: true}); //remote url
Mohammad Raheem
  • 1,131
  • 1
  • 13
  • 23
2

I had the same error.

I decided to visit infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP which returns the message "Session ID unknown".

Did you use multiple nodes ? If this is the case, please refer to the site https://socket.io/docs/using-multiple-nodes/.

As it says on the official site,

If you plan to distribute the load of connections among different processes or machines, you have to make sure that requests associated with a particular session id connect to the process that originated them.

This is due to certain transports like XHR Polling or JSONP Polling relying on firing several requests during the lifetime of the “socket”. Failing to enable sticky balancing will result in the dreaded:

Error during WebSocket handshake: Unexpected response code: 400

Reconfigure the Nginx config as explain then try to adapt the Express like this

let port = parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);
server.listen(port, console.log("Server running "+port));

Let us know if it changes something :)

phenric
  • 307
  • 1
  • 8
  • 15
  • Hey no I don't use multiple nodes. I think in my particular case the problem is the nginx server in between which i cannot configure because WebFaction hosting does not allow this... It would be nice to find a workaround though... – Aerodynamika Nov 21 '18 at 16:31
  • Thank you, it was my case, — I was needed to modify Nginx configuration, because Nginx was preventing connections to be established. – AntonAL Sep 15 '19 at 13:07
0

Try this two method if this work for you

Try this method 1:

I was facing the same issue. After 30 min debug I resolved the issue by enabling ALB (Application Load Balancer) Stickiness. It worked for me.

Try this method 2:

// Client side adding transport param:
var socket = io('http://localhost:3000', { transports: ['websocket'] });

You can set this value 'http://localhost:3000' as per your domain.

Manjunath Bilwar
  • 2,215
  • 19
  • 16
0

I got this problem when I updated packages on the backend, python socketio, but didn't do it on the frontend.

But when I updated the packages everywhere, the problem was fixed. This was a problem in versions

I found this error in the browser after navigating to the link when the 400 error returned "The client is using an unsupported version of the Socket.IO or Engine.IO protocols"