Nginx – Using nginx to proxy multiple instances of sockets.io

nginxproxypasssocket

I have two separate node.js applications running behind nginx. Both the apps use socket.io and express. One is served on port 5000 and the other on port 5001. But we need them both accessed through port 80 so that when a client accesses http://example.com/app1 they are forwarded to the first app, and http://example.com/app2 the second app.

When we had just one application, we had this setup in the nginx Sites Enabled config file:

   location /app1/ {
            proxy_pass http://127.0.0.1:5000/;
    }


    location /socket.io {
            proxy_pass http://127.0.0.1:5000/socket.io/;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_http_version 1.1;
    }

That worked fine. However, now that we are adding in a second app I'm not sure how to set up the forwarding. Clearly, socket.io can't forward to 5000 anymore, since connections from app2 need to connect over 5001.

Surely there must be a way to specify the socket.io forwarding as a subdomain of each of the apps, but I don't know what that would be.

Any advice you could give me would be much appreciated.

Best Answer

I was having the exact problem and I found this simple workaround :

Configure your client socket.io from your js/html file to connect from subdirectory (The default socket.io setting will have your socket.io connection routes to http://example.com/socket.io). you can find out how to do that here : get socket.io running from subdirectory.

so you'll want this on your client file:

var socket = io.connect('http://example.com', {path: "/app1socket"});

and for other app :

var socket = io.connect('http://example.com', {path: "/app2socket"});

And then, as you did before, make routes for every application socket in the nginx :

location /app1socket/ {
    proxy_pass http://127.0.0.1:3000/socket.io/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

location /app2socket/ {
    proxy_pass http://127.0.0.1:4000/socket.io/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

Assuming the reason your apps running under nginx is to proxy a http request to a locally running app, leave your server file configuration by standard setting.

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(4000, '127.0.0.1');

You can now make multiple socket.io applications under nginx.

Related Topic