Skip to content

Very slow with socket.io? #211

Closed
vicngtor opened this Issue Mar 16, 2012 · 12 comments

5 participants

@vicngtor

I currently have this set up:

port 80: note-http-proxy
port 3000: rails
port 8888: nodejs server (connection made via socket.io)

I have the following in my node-http-proxy:

var reverseProxy = httpProxy.createServer(function(req, res, proxy) { 
  var uri = url.parse(req.url);

  if (uri.pathname.match('/socket.io/')) { 
    proxy.proxyRequest(req, res, {
      host: 'localhost', 
      port: CONFIG.NODEJS_PORT
    });
  } else {
    proxy.proxyRequest(req, res, {
      host: 'localhost', 
      port: CONFIG.RAILS_PORT
    });
  }
}); 

basically any socket.io connection will be forced to port 8888.

When I run this on firefox, I am noticing the following error:

When I run this on chrome, I am seeing about a 10 second delay before socket.io can make its first communication.

Please look at the screen shot at http://i.imgur.com/Y0rHk.png

@vicngtor

So I did a little hacking and I found something:

I ditched node-http-proxy and switched over to nginx with the following setup:

nginx.conf:

server {
    listen  80;
    server_name  www.mysite.com;
    root /Users/vicngtor/mysite/rails/public;
    passenger_enabled on;

    location /socket.io { 
      proxy_pass http://localhost:8888;
    }
}

To my surprise, I am seeing the same delay! Actually, this wasn't a delay because no connection could be made.

I realized that the delay was caused by socket.io degrading to "lower" levels of communication.

As far as I know, node-http-proxy supports WebSockets. Why am I seeing this delay with node-http-proxy?

@jfhbrook

http-proxy definitely supports websockets. Most likely something in your code is amiss.

@jfhbrook

To my surprise, I am seeing the same delay!

nginx does not support websockets.

@vicngtor

@jesusabdullah fyi https://github.com/LearnBoost/socket.io/wiki/Nginx-and-Socket.io

I kind of gave up on http-proxy already sorry.

@coderarity

Oh, this is easy. It's proxy.proxyWebSocketRequest. See the README, under "Proxying WebSockets".

@mhseiden
mhseiden commented Apr 6, 2012

@vicngtor I had the exact same issue and @CodeRarity's solution fixed it immediately.

@vicngtor
vicngtor commented Apr 7, 2012

Oh thanks guys definitely will check it out.

@vicngtor
vicngtor commented Apr 9, 2012

I am still having trouble. Anyone willing to help me out?

My new server.js

var proxy = new httpProxy.HttpProxy({ 
  target: { 
    host: 'localhost', 
    port: CONFIG.RAILS_PORT,
  }
});

var server = http.createServer(function(req, res) { 
  //
  // Proxy normal HTTP requests
  //
  proxy.proxyRequest(req, res);
});

server.on('upgrade', function(req, socket, head) { 
  // 
  // Proxy websocket request to another port 
  //
  console.log('inside upgrade');
  proxy.proxyWebSocketRequest(req, socket, head, {
    host: 'localhost', 
    port: CONFIG.NODEJS_PORT
  });
});

server.listen(80);


var WrappedServer = require('./wrappedServer').WrappedServer
var singleton = new WrappedServer();
singleton.run(CONFIG.NODEJS_PORT, {'log level': 2});

My client.js

var socket = io.connect('http://localhost', {'sync disconnect on unload': false});

I am basically getting an error from io.connect. The response is a ROUTING_ERROR html page from my rails server.

Anyone here knows how I can get Socket.io to work with node-http-proxy's socket.io('upgrade') ?

Thanks

@mhseiden
mhseiden commented Apr 9, 2012

You're listening for the upgrade request on port 80, thus you proxy the WebSocket request to the RoR server. You need to use another proxy object where the target is the host and port for the Node/Socket.IO instance.

I think you're going to run into more issues though... Socket.io uses HTTP to perform the auth handshake and to ping the server every once and a while. So while all of your HTTP UPGRADE requests will proxy correctly, Socket.IO requests meant for the Nodejs instance will actually hit the RoR server.

I ran into this with an app I'm working on... A good solution is to use different subdomains for the WebSocket requests and the RoR requests. That way you can use a specific proxy based on the subdomain given in the headers.

@vicngtor
vicngtor commented Apr 9, 2012

@mhseiden I see.

Do you by any chance have that code available for me to use as a guide?

Thanks

@mhseiden

I made a Gist of a proxy that's been working fine for me. Not sure how it'll handle load (though that's more a question about node-http-proxy in general) but it works just fine for development.

https://gist.github.com/2347637

@indexzero
nodejitsu member

This looks fixed.

@indexzero indexzero closed this May 9, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.