Using node http-proxy to proxy websocket connections

点点圈 提交于 2019-12-20 09:49:07

问题


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.


回答1:


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.




回答2:


Do you need both servers? If not you could use the same server for static files and to listen for socket connections:

// make the http server
var express = require('express'),
    app = express(), server = require('http').createServer(app),
    io;

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

server.listen(8080);

// listen for socket connections
io = require('socket.io').listen(server);

// socket stuff here


来源:https://stackoverflow.com/questions/21629752/using-node-http-proxy-to-proxy-websocket-connections

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!