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 ?
'
Configuring Proxy ServerCreate a new conf file for the Nginx server that will accept WebSocket requests. Saving your settings and then restart the NGINX server will enable it to support WebSocket connections.
NGINX supports WebSocket by allowing a tunnel to be set up between both client and back-end servers. NGINX will send the Upgrade request from the client to the back-end server, the Upgrade and Connection headers must be set explicitly. Once this is done, NGINX deals with this as a WebSocket connection.
The benefits of using Nginx as a reverse proxy include: Clients access all backend resources through a single web address. The reverse proxy can serve static content, which reduces the load on application servers such as Express, Tomcat or WebSphere.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With