3

I'm interested in setting up a Socket.IO server + Rails web application. However, as many are aware, there are not many web servers that support WebSockets. Here have been my 2 attempts so far:

  1. I tried the Nginx-module route. Couldn't get the combinations of compilations + configurations to get this fully working. Probably something dumb on my part.

    http://www.letseehere.com/reverse-proxy-web-sockets

  2. I tried writing my own web server with node-http-proxy but I had trouble fully integrating this with Socket.IO, despite reading all the tutorials.

    http://github.com/nodejitsu/node-http-proxy

  3. I tried writing my own web server with bouncy.js but it's horribly slow. Could be my code, could be the framework. I have no idea.

    http://github.com/substack/bouncy

These are the things I've tried, and I'm just curious who else has gone down these routes and finally got something work (and of course, what they did to get it working).

Community
  • 1
  • 1
robinhoode
  • 201
  • 3
  • 6
  • The question is unclear, what is your goal? Proxying to rails?. In an attempt to provide useful information: I've set up socket.io with node.js with little difficulty, but I use it as a standalone webserver (with express.js usually) – Chris Biscardi Dec 25 '11 at 05:07
  • @ChrisBiscardi I'd like to hear from anyone who has gotten Socket.IO working alongside a Rails application, and what steps they took to get it working... The problem with express.js is that (1) I've already got a lot of legacy Rails code and (2) the two frameworks for integrating WebSockets I've used, and my results are listed above. – robinhoode Dec 25 '11 at 08:26

3 Answers3

6

As per alessioalex's request, here's my configuration file. I deleted all the existing comments but added a few that I, myself, would not have figured to be important.

However, describing what all the parts of this config does is out of the scope of this post, but you can likely find the necessary documentation on the HAProxy website.

global
    maxconn 4096 
    pidfile /var/run/haproxy.pid

defaults
    mode    http

frontend all
    bind 0.0.0.0:80
    mode tcp

    maxconn 200000
    timeout client 86400000
    default_backend www_backend

    # Any URL beginning with socket.io will be flagged as 'is_websocket'
    acl is_websocket path_beg /socket.io
    acl is_websocket hdr(Upgrade) -i WebSocket
    acl is_websocket hdr_beg(Host) -i ws

    # The connection to use if 'is_websocket' is flagged
    use_backend socket_backend_http if is_websocket

    tcp-request inspect-delay 500ms
    tcp-request content accept if HTTP   

backend www_backend
    option httplog
    option httpclose
    balance roundrobin
    option forwardfor
    timeout server 30000
    timeout connect 4000
    server thin1 localhost:4001 weight 1 maxconn 1024 check
    server thin2 localhost:4002 weight 1 maxconn 1024 check
    server thin3 localhost:4003 weight 1 maxconn 1024 check

backend socket_backend_http
    mode http
    option httplog
    option http-server-close
    option forceclose
    no option httpclose
    balance roundrobin
    option forwardfor 
    timeout queue 5000
    timeout server 86400000
    timeout connect 86400000
    timeout check 1s
    server socket1 localhost:5001 weight 1 maxconn 1024 check
robinhoode
  • 201
  • 3
  • 6
  • 1
    I had problems with this config. although it is very close. this version worked for me with copy paste. http://stackoverflow.com/questions/4360221/haproxy-websocket-disconnection – Pete Brumm Feb 01 '12 at 02:33
0

Here is a node.js socket.io server. note that this only handles websockets.

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(8080);

function handler (req, res) {}

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

and the corresponding client:

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

run node server.js to start up the node server and request the index.html from rails.

If you need to call rails functions from the websocket server you can communicate over http using either the http node module or this library: https://github.com/mikeal/request

Chris Biscardi
  • 3,148
  • 2
  • 20
  • 19
  • Thanks for this write up. I've seen the documentation on http://socket.io so I'm well aware this is the starting point. The question I'm asking in this post is how to handle both WebSockets and standard HTTP requests at the same time. – robinhoode Dec 25 '11 at 11:00
  • This will do that. Your legacy Ruby code on port 80 and node/websockets on port 8080. Do you want to handle HTTP with node? – Chris Biscardi Dec 25 '11 at 11:34
0

You can use bouncy, but I'd recommend HAProxy, which is a better solution for highly trafficked websites. Check this question for a sample configuration: HAProxy + WebSocket Disconnection

I would recommend using HAProxy + Nginx for serving static files + Node for dynamic stuff & websockets (Socket.IO).

node-http-proxy is having problems with WebSockets in Node 0.6.x, so you cannot use that at the moment unfortunately.

Community
  • 1
  • 1
alessioalex
  • 62,577
  • 16
  • 155
  • 122
  • Just got this working. Didn't follow any one tutorial all the way through, but a collage of tricks seemed to work. Looks like I'll be using HAProxy more in the future. – robinhoode Dec 26 '11 at 03:41
  • @robinhoode that's great, maybe you can post a configuration here so people can check it out later. I'm played a little with HAProxy and need to implement it in my next project, but so far it has been great. Trello.com uses it in production for example. – alessioalex Dec 26 '11 at 09:37