NGINX configuration to work with Socket.IO

Problem

So I have been trying to get this to work 2 days and I am stuck. This is my first time configuring a server for rails that uses NodeJS+Socket IO. I am a noob with NGINX and Unicorn. Basically the NodeJS+SocketIO part of my app will push messages to users who are connected to my app. This is my nginx.conf

server{
    listen 80 default;
    root /home/deployer/saigon/public;
    try_files $uri/index.html $uri @unicorn;

    location /sockets {
        proxy_pass http://localhost:3210;
    }

    location @unicorn {
       proxy_pass http://localhost:3000;
    }
}

And in my production.rb, I have configured the url which the user will have to send message to/receive message from

SOCKET_IO_URL ='http://localhost:8080/sockets

Why 8080? I use Vagrant to forward 8080 -> 80

I tried accessing http://localhost:8080/sockets and I was able to get the socket welcome message. I looked at my NodeJS server log and it was receiving messages alright. However, when it comes to broadcasting..... it just does not do it. Has anyone ever gotten this kind of app to work with the set up I am trying to do? Should I just go with Apache + Unicorn ?

'

Problem courtesy of: denniss

Solution

Updated Answer

I have finally figured out a way to get this working. It's not at all obvious, but when hosting socket.io on a subfolder, you do NOT use the subfolder in the connect statement. This is what I was doing before and the client was never receiving a response.

Not Working

<script src="/test/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost:8080/test/', {resource:'test/socket.io'});
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>

http://localhost:8080/test/ This is the part which is throwing things off. That creates a namespace for the local socket which the server side does not respect. So the client sends the message on the namespace '/test/' but the server responses are going to an empty namepace '' so the client never gets the messages. The workaround it to simply remove the '/test/' and make sure you are using the resource variable on the client and the server.

Working!

<script src="/test/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost:8080', {resource:'test/socket.io'});
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>

I hope this helps you get things working on your end.

Original Answer

It is not a problem with your setup, it is a problem of socket.io not wanting to work on sub folder. I would bet willing to be that if you dropped the /sockets your example would work fine. I ran into the exact same problem when using http-node-proxy trying to host socket.io connections on subfolders. There was a bug created a while ago, but it was closed out and never resolved.

https://github.com/LearnBoost/socket.io-client/issues/185

https://github.com/LearnBoost/socket.io/issues/320

I am still looking for a solution as well, but I have a feeling I'm going to have to roll up my sleeves and dig into the code myself.

Solution courtesy of: Timothy Strimple

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.