Nodejs代理到另一个端口

5
我希望在我的服务器上运行一个节点进程。
对于 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)

但我了解'路由器(router)'现在已经被弃用。

我已经做了好几个小时了!

2个回答

2

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

修改 apache2 配置文件,使其仅监听回环接口:

vim /etc/apache2/ports.conf

将 "Listen 80" 改为 "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

的意思是运行一个名为"server.js"的Node.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
我建议用nginx替换apache,它更加适合。 - Zlatko
是的,但我习惯于使用Apache2,并且在此服务器上运行其他为Apache2设置的站点。我知道nginx更优秀,只是我还没有准备好立即更改! - Eamorr
放弃上述代码。这里有一个更加简洁的Apache2/socket.io解决方案:http://serverfault.com/questions/616370/configuring-apache-2-4-mod-proxy-wstunnel-for-socket-io-1-0 - Eamorr

1

我正在使用它作为反向代理。已测试过Node 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

欢迎提出任何更好的建议。

本答案源自 此回答


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接