node-http-proxy
node-http-proxy copied to clipboard
Express + http-proxy + websockets
I'm trying to run a proxy server on port 8081 that can re-route http traffic and socket.io traffic. I'm using express server because I use passport for authentication.
I can get http-proxy to route all http traffic on 8081 and all websocket traffic directed to 8082, but I cant figure out how to handle both protocols on one port. Ideas?
This first technique just causes client-side xhr requests to hit the server at a rate of about 3 requests per second.
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var bodyParser = require('body-parser');
//Enable Gzip
app.use(compress());
var postingAPI = 'http://localhost:4043',
realtimeAPI = 'ws://localhost:4044',
notificationAPI = 'http://localhost:4444';
app.all("/v1/postings/*", function(req, res) {
console.log('redirecting to posting api');
apiProxy.web(req, res, {target: postingAPI});
});
app.all("/v1/queues/*", function(req, res) {
console.log('redirecting to notification api');
apiProxy.web(req, res, {target: notificationAPI});
});
app.on('connection', function (req, socket, head) {
apiProxy.ws(req, socket, head, {
target: realtimeAPI
});
});
app.on('join-room', function (req, socket, head) {
apiProxy.ws(req, socket, head, {
target: realtimeAPI
});
});
app.use(bodyParser.json()); // get information from html forms
app.use(bodyParser.urlencoded({
extended: true
}));
// start Node server ===========================================================
app.listen(8081);
This second method catches the websocket request, but obviously doesn't get upgraded.
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var bodyParser = require('body-parser');
//Enable Gzip
app.use(compress());
var postingAPI = 'http://localhost:4043',
realtimeAPI = 'ws://localhost:4044',
notificationAPI = 'http://localhost:4444';
app.all("/v1/postings/*", function(req, res) {
console.log('redirecting to posting api');
apiProxy.web(req, res, {target: postingAPI});
});
app.all("/v1/queues/*", function(req, res) {
console.log('redirecting to notification api');
apiProxy.web(req, res, {target: notificationAPI});
});
app.all("/socket.io/*", function(req, res) {
console.log('redirecting to realtime api');
apiProxy.web(req, res, {target: realtimeAPI});
});
app.use(bodyParser.json()); // get information from html forms
app.use(bodyParser.urlencoded({
extended: true
}));
// start Node server ===========================================================
app.listen(8081);
I've tried a 3rd method using .ws method but no luck there either.
app.all("/socket.io/*", function(req, socket, head) {
console.log('redirecting to realtime api');
apiProxy.ws(req, socket, head, {target: realtimeAPI});
});
+1
@that1guy Did you see the example in the readme, that listens on "upgrade"?
did this get resolved? I'm having similar issues. Upgrade didn't catch the /socket.io request and thus was never reached.
I was also having similar issues proxying socket.io connections, which I've now solved! Heres an example that might help: https://github.com/MethodGrab/socketio-proxy-boilerplate.
Facing same issue. As a workaround I removed express.It works fine after that.
I also faced the same issue, I'm using different express middlewares which should also run on websocket connection attempts and removing express was not an option.
I implemented proxying for websockets via manually proxying the messages - I've put together some proof-of-concept code here, happy if it helps anybody: https://gist.github.com/frow/eb0b649bce510587299741d34dc486c5
I ended up wrapping the express instance in http.createServer
.
Looks a bit like this:
import * as http from "http";
const server = http.createServer(app); // where app is the Express app
const httpProxy = require("http-proxy");
const proxy = httpProxy.createProxyServer({ target: "http://localhost:3001", ws: true });
app.use((req, res) => proxy.web(req, res));
server.on("upgrade", (req, socket, head) => {
proxy.ws(req, socket, head);
});
server.listen(port, () => {
console.log("Listening at http://localhost:" + port + "/");
});