简体   繁体   中英

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

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 !

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. ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM