Nodejs代理到另一个端口

时间:2014-09-06 18:05:52

标签: node.js proxy

我想在我的服务器上运行一个节点进程。

http://mysite.me:80/的请求应转到http://localhost:8000

http://mysite.me:80/xxx的请求应转到http://localhost:8001

我曾经做过类似的事情:

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

但我明白'路由器'现已弃用。

我已经在这几个小时了!

2 个答案:

答案 0 :(得分:1)

是的,所以我把它全部搞定了......

修改apache2,使其只侦听loopback接口:

vim /etc/apache2/ports.conf

改变"听80" to" Listen 127.0.0.1:80"

让你的socket.io服务器(" server.js")监听端口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

现在你需要一个代理(" proxy.js")监听你的公共接口(x.x.x.x:80)

它根据需要在apache2和socket.io之间拆分流量

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

这里是网页的HTML / jQuery:

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

现在我需要一种方法来弄清楚如何确保proxy.js不会出现问题并且可以防范!

答案 1 :(得分:0)

我将它用于反向代理。使用节点v8.1.3进行测试。

使用内置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)

将其放入文件proxy.js并尝试使用:

sudo node proxy.js &

服务器启动后:

curl localhost/xxx
curl localhost

关于sudo的说明

我不建议以root用户身份运行脚本。尽管如此,为了使用端口80,我个人正在使用

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

欢迎任何更好的建议。

这个答案来自this answer