Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using node http-proxy to proxy websocket connections

I have an application that uses websockets via socket.io. For my application I would like to use a separate HTTP server for serving the static content and JavaScript for my application. Therefore, I need to put a proxy in place.

I am using node-http-proxy. As a starting point I have my websockets app running on port 8081. I am using the following code to re-direct socket.io communications to this standalone server, while using express to serve the static content:

var http = require('http'),
    httpProxy = require('http-proxy'),
    express = require('express');

// create a server
var app = express();
var proxy = httpProxy.createProxyServer({ ws: true });

// proxy HTTP GET / POST
app.get('/socket.io/*', function(req, res) {
  console.log("proxying GET request", req.url);
  proxy.web(req, res, { target: 'http://localhost:8081'});
});
app.post('/socket.io/*', function(req, res) {
  console.log("proxying POST request", req.url);
  proxy.web(req, res, { target: 'http://localhost:8081'});
});

// Proxy websockets
app.on('upgrade', function (req, socket, head) {
  console.log("proxying upgrade request", req.url);
  proxy.ws(req, socket, head);
});

// serve static content
app.use('/', express.static(__dirname + "/public"));

app.listen(8080);

The above application works just fine, however, I can see that socket.io is no longer using websockets, it is instead falling back to XHR polling.

I can confirm that by looking at the logs from the proxy code:

proxying GET request /socket.io/1/?t=1391781619101
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294
proxying POST request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=1391781629
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294

Does anyone know how to proxy the web sockets communication? All the examples from node-http-proxy assume that you want to proxy all traffic, rather than proxying some and serving others.

like image 375
ColinE Avatar asked Feb 07 '14 14:02

ColinE


People also ask

Does HTTP proxy support WebSocket?

Summary. While the HTML5 Web Socket protocol itself is unaware of proxy servers and firewalls, it features an HTTP-compatible handshake so that HTTP servers can share their default HTTP and HTTPS ports (80 and 443) with a WebSocket server.

How many WebSocket connections can a Nodejs server handle?

The theoretical limit is 65k connections per IP address but the actual limit is often more like 20k, so we use multiple addresses to connect 20k to each (50 * 20k = 1 mil).

Is Node JS good for WebSockets?

Node. js can maintain many hundreds of WebSockets connections simultaneously. WebSockets on the server can become complicated as the connection upgrade from HTTP to WebSockets requires handling. This is why developers commonly use a library to manage this for them.


1 Answers

Just stumbled upon your question, and I see that it is still not answered. Well, in case you are still looking for the solution... The problem in your code is that app.listen(8080) is just syntactic sugar for

require('http').createServer(app).listen(8080)

while app itself is just a handler function, not an instance of httpServer (I personally believe that this feature should be removed from Express to avoid confusion). Thus, your app.on('upgrade') is actually never used. You should instead write

var server = require('http').createServer(app);
server.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head);
});
server.listen(8080);

Hope, that helps.

like image 95
Dmitry Avatar answered Oct 03 '22 18:10

Dmitry