Nodejs proxy to another port

喜欢而已 提交于 2020-01-23 10:42:05

问题


I want to run a node process on my server.

Requests to http://mysite.me:80/ should go to http://localhost:8000

Requests to http://mysite.me:80/xxx should go to http://localhost:8001

I used to do something like:

httpProxy = require('http-proxy');
var options = {
    router: {
        'mysite.me': 'localhost:8000',
        'mysite.me/xxx': 'localhost:8001'
    }
};
httpProxy.createServer(options).listen(80)

But I understand 'router' is now deprecated.

I've been at this for hours!


回答1:


Right, so I got it all working...

Modify apache2 so it only listens on loopback interface:

vim /etc/apache2/ports.conf

Change "Listen 80" to "Listen 127.0.0.1:80"

Have your socket.io server ("server.js") listening on port 8001:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(8001);

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  /*socket.on('my other event', function (data) {
    console.log(data);
  });*/
});

node server.js

Now you need a proxy ("proxy.js") listening on your public interface (x.x.x.x:80)

It splits traffic between apache2 and socket.io as appropriate

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

var routes = [
  'http://127.0.0.1:80',
  'http://127.0.0.1:8001'
];

var proxy = new httpProxy.createProxyServer({});

var proxyServer = http.createServer(function (req, res) {
    var route=0;
    var split1=req.url.split('/');
    if (split1.length>0) {
        if(split1[1]=="socket.io"){   //requests to "socket.io" get tapped off to nodejs
            route=1;
        }
    }

    proxy.web(req, res, {target: routes[route]});
});
proxyServer.on('upgrade', function (req, socket, head) {
    proxy.ws(req, socket, head, {target: routes[1]});
});
proxyServer.listen(80,"x.x.x.x");
//proxyServer.listen(80,"ip:v6:address");   //optional...

sudo node proxy.js

And here's the HTML/jQuery for the web page:

<script src="./lib/socket.io/socket.io-1.1.0.js"></script>
<script>
$(document).ready(function(){
    var socket = io.connect('http://www.mysite.me:80');   //where mysite.me resolves to x.x.x.x
    socket.on('news', function (data) {
        console.log(data);
        socket.emit('my other event', { my: 'data' });
    });
});
</script>

Now I need a way to figure out how to make sure proxy.js doesn't go down and is hammer proof!




回答2:


I'm using it for a reverse proxy. Tested with node v8.1.3.

Solution using builtin http.request

#!/usr/bin/env node

http = require('http')
http.createServer((req, res) => {
  var port = (/\/xxx/.test(req.url)) ? 8001 : 8002
  _req = http.request(
    {port, path:req.url, headers:req.headers, method:req.method}, 
    (_res) => {
      res.writeHead(_res.statusCode, _res.headers)
      _res.pipe(res)
    }
  )
  _req.on('error', (e) => {
      console.error('proxied request failed: '+e.message)
      res.writeHead(500)
      res.end()
  })
  req.pipe(_req)
}).listen(80, () => console.log('listening on port 80...'))

// for verfication purpose only:
http.createServer((req, res) => {res.writeHead(200);res.end('server on 8001')}).listen(8001)
http.createServer((req, res) => {res.writeHead(200);res.end('server on 8002')}).listen(8002)

Place it into the file proxy.js and try it out with:

sudo node proxy.js &

And after the server started:

curl localhost/xxx
curl localhost

NOTE on sudo

I do not recommend running the script as root user. To use port 80 nonetheless, I am personally using

sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j DNAT --to-destination 127.0.0.1:8080

Any better suggestions are welcome.

This answer was derived from this answer.



来源:https://stackoverflow.com/questions/25703249/nodejs-proxy-to-another-port

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