Getting Node-http-proxy to work with socket.io?
Asked Answered
T

1

6

I am trying to use node-http-proxy to direct traffic to port 3000 (my rails server) and port 8888 (my nodejs socket.io server). I am using node-http-proxy to act as a reverse proxy sitting on port 80.

(I pretty much just copy the README from node-http-proxy)

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});

And this is my client.js on the browser.

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

Somehow, io.connect is unable to connect to the nodejs server. I am getting this response from the io.connect:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }

    body, p, ol, ul, td {
      font-family: helvetica, verdana, arial, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }

    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }

    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>

<h1>Routing Error</h1>
<p><pre>No route matches [GET] &quot;/socket.io/1&quot;</pre></p>
</body>
</html> 

Any idea how I can get io.connect to connect to the nodejs server? I don't know how I can trigger io.connect to get to the server.upgrade bloc.

Thanks !

Tevere answered 9/4, 2012 at 7:19 Comment(1)
I have pretty much the same problem. Did you find any workaround for this one ?Beutler
S
3

With socket.io, you first perform a http handshake. This step does not involves websocket connection. The above code that you have quoted from the readme section of http-proxy github page is telling how to listen for websocket requests directly. Here, you need a normal routing entry(using HTTP resources) for socket.io and when the handshake completes, your connection will upgrade to websocket and the proxy will automatically handle it.

Here is a pseudo code. I am using it in production to proxy to multiple socket-io servers which are identified by actual physical resources(HTTP resources).

Suppose I have two socket.io servers running on the following ip and port as follows-

  1. ip1:3000
  2. ip2:3001

Now the code in our proxy(with ip ip3) will look like-

var options = {
  "ip3/Socket1/socket.io" : "ip1:3000/socket.io",
  "ip3/Socket2/socket.io" : "ip2:3001/socket.io"
}

proxy = require('http-proxy').createServer(options).listen(80);

Some points to note here-

  • Here I am using Socket1 and Socket2 as aliases for identifying the first and the second socket-io servers respectively.
  • You can proxy to any machine as long as you have access to it. i.e. you are able to ping those machines(ip1 and ip2 here) from your proxy server(ip3 here) and there is no firewall blocking your connection(you are part of the same network).
  • If you have all of the above on the same host, you can replace ip1 and ip2 with localhost

The client side javascript code will look something like this for my current example-

var socket1 = io.connect('http://ip3:80', {'resource': 'Socket1/socket.io'});
var socket2 = io.connect('http://ip3:80', {'resource': 'Socket2/socket.io'});

All this looks like a lot to digest at once. Let me know if you still face issues with this.

Spineless answered 28/5, 2013 at 1:38 Comment(1)
I have some questions brotherIorgos

© 2022 - 2024 — McMap. All rights reserved.