2016-07-29 86 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,但這是有點複雜)。

希望這可以幫助別人!