节点http-proxy

时间:2015-08-03 22:01:46

标签: node.js socket.io sails.js http-proxy node-http-proxy

我试图将多个sails服务器放在同一台服务器上,为此我想把一个节点http-proxy重定向到正确服务器上的每个域,如下所示:

var http = require('http'),
    httpProxy = require('http-proxy'), 
    proxy = httpProxy.createProxyServer({}), 
    url = require('url'); 

http.createServer(function(req, res) 
{ 
    var hostname = req.headers.host.split(":")[0]; 
    var pathname = url.parse(req.url).pathname; 

    switch(hostname) 
    { 
        case 'example.com': 
            proxy.web(req, res, { target: 'http://localhost:8080' }); 
            break; 
        case 'dev.example.com': 
            proxy.web(req, res, { target: 'http://localhost:8081' }); 
            break; 
        default: 
            proxy.web(req, res, { target: 'http://localhost:80' }); 
    } 
}).listen(80, function() { 
    console.log('proxy listening on port 80'); 
});

但是在调用新页面后我有这个错误和代理崩溃:

/var/www/default/node_modules/http-proxy/lib/http-proxy/index.js:119
    throw err; 
          ^ 
Error: socket hang up 
    at createHangUpError (_http_client.js:215:15) 
    at Socket.socketCloseListener (_http_client.js:247:23) 
    at Socket.emit (events.js:129:20)
    at TCP.close (net.js:485:12)

我想我错过了一些转发套接字的代码,但我怎么能这样做呢?这种代理对于生产是否足够强大?

2 个答案:

答案 0 :(得分:1)

您只处理http请求的代理,您还应处理socket请求。

这是一个小技巧,您可以在应用中添加逻辑。

proxyServer.on('upgrade', function (req, socket, head) {

    console.log(req)
    proxy.ws(req, socket, head);
});

答案 1 :(得分:1)

最后我用这个: https://gist.github.com/jaumard/047f10b7c0563b4bd045

它处理http和套接字,并检查网站是否还活着,如果它不是它发送维护页面。

/**
 * Node.js proxy to redirect domain to correct server
 * Also check is server is alive or send a maintenance page
 */
var http = require('http'),
    httpProxy = require('http-proxy'),
    proxy = httpProxy.createProxyServer({}),
    request = require('request'),
    domains = {
    "domain1.com" : "localhost:8080",
    "dev.domain1.com" : "localhost:8081",
    "domain2.com" : "localhost:8082",
    "default" : "localhost:8080"
};

var maintenance = "<!DOCTYPE html>"+ "<title>Site Maintenance</title>" + "<style>" + "  body { text-align: center; padding: 150px; }" + "  h1 { font-size: 50px; }" + "  body { font: 20px Helvetica, sans-serif; color: #333; }" + "  article { display: block; text-align: left; width: 650px; margin: 0 auto; }" + "  a { color: #1bbc9b; text-decoration: none; }" + "  a:hover { color: #109a7e; text-decoration: none; }" + "</style>" + "<article>" + "    <h1>We&rsquo;ll be back soon!</h1>" + "    <div>" + "        <p>Sorry for the inconvenience but we&rsquo;re performing some maintenance at the moment. If you need to you can always <a href=\"mailto:me@me.com\">contact us</a>, otherwise we&rsquo;ll be back online shortly!</p>" + "        <p>&mdash; My Team</p>" + "    </div>" + "</article>";

//Check is server is alive, if not respond a maintenance page
var checkServerAvailability = function (req, res, url)
{
    request(url + '/isAlive', function (error, response, body)
    {
        if (!error && response.statusCode == 200)
        {
            proxy.web(req, res, {target : url});
        }
        else
        {
            res.writeHeader(503, {"Content-Type" : "text/html"});
            res.write(maintenance);
            res.end();
        }
    });
};

var server = http.createServer(function (req, res)
{
    var hostname = "";
    //If server call with domaine and not call with IP directly
    if (req.headers.host)
    {
        hostname = req.headers.host.split(":")[0];
    }

        //If it's a know domain, redirect to correct server
    if (domains[hostname])
    {
        checkServerAvailability(req, res, 'http://' + domains[hostname]);
    }
    else
    {
        checkServerAvailability(req, res, 'http://' + domains["default"]);
    }
});

// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
server.on('upgrade', function (req, socket, head)
{
    var hostname = "";
    //If server call with domaine
    if (req.headers.host)
    {
        hostname = req.headers.host.split(":")[0];
    }

    //If it's a know domain, redirect to correct server
    if (domains[hostname])
    {
        proxy.web(req, socket, {target : 'ws://' + domains[hostname]});
    }
    else
    {
        proxy.web(req, socket, {target : 'ws://' + domains["default"]});
    }
});

//Catch error to prevent proxy crash
proxy.on('error', function (err)
{
    console.error(err);
});

server.listen(80, function ()
{
    console.info('proxy listening on port 80');
});