2016-07-29 56 views
1

我一直无法找到任何文档/我的需求的答案。http-proxy-rules和Websockets

我在一个泡菜的东西。我正在开发一个websocket应用程序,它将允许通过创建新服务(websocket服务器)来扩展模块。当然这意味着需要连接更多的端口。问题是,我们的公司政策只有很少的端口打开,所以我需要代理我的请求。

我读过很多回答说使用NGINX,但我根本不能。首先,我正在运行Windows,其次我们公司对可以使用和不能使用的内容非常严格。不过,我可以安装任何节点模块。我试图将http-proxy模块和http-proxy-rules一起使用。

问题是,我得到404的每个websocket请求。我会注意到,默认代理(对于普通的web服务,而不是套接字)正在100%正常工作。

这里是我当前的代码:

var http = require('http'), 
     httpProxy = require('http-proxy'), 
     HttpProxyRules = require('http-proxy-rules'); 

    // Set up proxy rules instance 
    var proxyRules = new HttpProxyRules({ 
    rules: { 
     '.*/ws/admin': 'http://localhost:26266', // Rule for websocket service (admin module) 
     '.*/ws/quickquery': 'http://localhost:26265' // Rule for websocket service (quickquery module) 
    }, 
    default: 'http://Surface.levisinger.com:8080' // default target 
    }); 

    // Create reverse proxy instance 
    var proxy = httpProxy.createProxy(); 

    // Create http server that leverages reverse proxy instance 
    // and proxy rules to proxy requests to different targets 
    http.createServer(function(req, res) { 

    // a match method is exposed on the proxy rules instance 
    // to test a request to see if it matches against one of the specified rules 
    var target = proxyRules.match(req); 
    if (target) {  
     //console.log(req); 
     console.log("Returning " + target + " for " + req.headers.host); 
     return proxy.web(req, res, { 
     target: target, 
     ws: true 
     });  
    } 

    res.writeHead(500, { 'Content-Type': 'text/plain' }); 
    res.end('The request url and path did not match any of the listed rules!'); 
    }).listen(5050); 

我连接到的WebSocket客户端代码如下所示:

var servPath = (cliSettings["AppPaths"]["Admin"] == null) ? 'http://' + window.location.hostname + ':5050' : cliSettings["AppPaths"]["Admin"], 
    AdminIO = new io(servPath, { 
     extraHeaders: { 
      Service: "Admin" 
     }, 
     path: '/ws/admin'}) 

...

和WebSocket的服务器被称为是这样的:

io = require('socket.io').listen(26266,{ path: '/ws/admin'}) // can use up to 26484 

我真的很希望这里有人会有一个想法。谢谢!

回答

0

想通了如何做到这一点。有几件事情需要... 1.如果你想代理它们,你必须使用自定义websocket路径。 2.当代理它们时,您必须将整个路径提供给websocket。 3.您需要指定一个事件来处理websocket(ws)流量。

下面是你们所有人的例子。

+++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++

代理服务器:

var ini = require('node-ini'), 
     conf = ini.parseSync('../settings/config.ini'), 
     http = require('http'), 
     httpProxy = require('http-proxy'), 
     HttpProxyRules = require('http-proxy-rules'); 

    // Set up proxy rules instance 
    var proxyRules = new HttpProxyRules({ 
    rules: { 
     '.*/ws/remote': 'http://' + conf["Server"]["binding"] + ':26267/ws/remote', 
     '.*/ws/admin': 'http://' + conf["Server"]["binding"] + ':26266/ws/admin', // Rule for websocket service (admin module) 
     '.*/ws/quickquery': 'http://' + conf["Server"]["binding"] + ':26265/ws/quickquery' // Rule for websocket service (quickquery module)  
    }, 
    default: 'http://' + conf["Server"]["binding"] + ':8080' // default target 
    }); 

    // Create reverse proxy instance 
    var proxy = httpProxy.createProxy(); 

    // Create http server that leverages reverse proxy instance 
    // and proxy rules to proxy requests to different targets 
    var proxyServer = http.createServer(function(req, res) { 

    // a match method is exposed on the proxy rules instance 
    // to test a request to see if it matches against one of the specified rules 
    var target = proxyRules.match(req); 
    if (target) {  
     //console.log(req.url); 
     //console.log("Returning " + target + " for " + req.url); 
     return proxy.web(req, res, { 
     target: target, 
     ws: true 
     });  
    } 

    res.writeHead(500, { 'Content-Type': 'text/plain' }); 
    res.end('The request url and path did not match any of the listed rules!'); 
    }).listen(conf["Server"]["port"]); 

// 
// Listen to the `upgrade` event and proxy the 
// WebSocket requests as well. 
// 
proxyServer.on('upgrade', function (req, socket, head) { 
    var target = proxyRules.match(req); 
    if (target) { 
     return proxy.ws(req, socket, head, { target: target });  
    } 
}); 
process.on('SIGINT', function() { 
    db.stop(function(err) { 
    process.exit(err ? 1 : 0); 
    }); 
}); 

WebSocket伺服器插座监听器:

io = require('socket.io').listen(26266,{ path: '/ws/admin'}); 

连接到从客户端页面的WebSocket:

AdminIO = new io({path: '/ws/admin'}); 

++++++++++++++++++++++++++++++++++ +++++++++++ +++++++++++++++++++++++++++++++++++++++ +++++++

上面的例子将通过端口80代理我的“管理”连接,它在端口26266上运行。(我当然会推荐在任何情况下使用443/SSL,但这是有点复杂)。

希望这可以帮助别人!