2015-04-12 118 views
0

我正在編寫node.js應用程序的任務管理器。這些應用程序在任意端口開啓,所以,爲了達到這些目標我想僞造他們的根在 這樣的URL:Socket.io在代理服務器收到握手響應之前關閉[ECONNRESET]

http://domain.com/proxy/yourApplication

那麼第三方可以使HTTP請求發送到他們的應用,但不知道在哪個端口運行。

然後我選擇http-proxy

var express = require('express') 
, router = express.Router() 
, Helper = require('../helper') 
, launcher = require('../launcher') 
, httpProxy = require('http-proxy') 
, proxy = httpProxy.createProxyServer({ws: true}); 

並偵聽在這條路線的代碼...

// Proxy 
router.use('/proxy/:name?', function(req, res) { 

    var app, reqPath, referer, proxyUrl; 

    // Capture the referer to proxy the request 
    // in case the path is not clear enaugh 
    if (req.get('referer') !== undefined) { 
    var aux = req.get('referer').split('/'); 
    referer = aux[aux.indexOf('proxy') + 1] 
    } 

    // This block returns an app object 
    // with the port where it is running 
    app = launcher.getApp(req.params.name) 
    || launcher.getApp(referer); 

    if (app) { 
    // Here app is running 

    // In case the path is /proxy/:name 
    // instead of /proxy/:name/ you need this block 
    req.url = (req.url === '/') ? '' : req.url; 
    reqPath = (referer !== undefined) 
    ? '/' + req.params.name + req.url 
    : req.url; 
    req.url = reqPath.replace('/proxy/', '/'); 
    req.url = req.url.replace('/' + app.name, ''); 

    // This block of code actually pipes the request 
    // to the running app and pass it to the client 
    proxyUrl = req.protocol + '://localhost:' + app.port; 
    proxy.web(req, res, { 
     target: proxyUrl 
    }); 

    // Some logging 
    console.log('req url: %s', req.url); 
    console.log('proxy url: %s', proxyUrl); 
    console.log('referer: %s', referer); 

    } else { 
    // Here app is not running 
    res.status(404).json("App not running"); 
    } 
}); 

它的工作原理只是大多數應用程序很好,但與插座打開應用時。它提示:

WebSocket connection to 'ws://localhost/proxy/xy-terminal/socket.io/1/websocket/gMqK_XRwZENuUibi4ekJ' failed: Connection closed before receiving a handshake response 

在服務器控制檯...

Trace: { [Error: socket hang up] code: 'ECONNRESET' } 
    at process.<anonymous> (/Users/jdario/Development/xy-dashboard/www:107:11) 
    at process.emit (events.js:107:17) 
    at process._fatalException (node.js:236:26) 
    at ProxyServer.emit (/Users/jdario/Development/xy-dashboard/node_modules/http-proxy/node_modules/eventemitter3/index.js:75:35) 
    at ClientRequest.proxyError (/Users/jdario/Development/xy-dashboard/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:140:16) 
    at ClientRequest.emit (events.js:129:20) 
    at Socket.socketCloseListener (_http_client.js:247:9) 
    at Socket.emit (events.js:129:20) 
    at TCP.close (net.js:485:12) 

由於它是僞造應用程序根目錄的「代理」,我可能無法單獨修改它們的源代碼,它們應該按預期工作。在正確的端口打開它們(在這種情況下爲3000)時,它們不會顯示任何錯誤。

預先感謝您!

+0

你知道一個webSocket連接是作爲一個http請求啓動的嗎?然後它被升級到webSocket協議?因此,您的代理需要處理該問題,並需要一種方法來告知哪個應用是webSocket連接的目的地。 – jfriend00

+0

是的!其實我相信這個錯誤可能在那裏,但經過檢查http-proxy的源代碼後,我找不到。另外,我必須指出,第一次完成後的其他連接試驗。第一個是在'/ proxy/appName /'和'完成'到達'/ proxy/appName'時的'pending'。 – jsdario

回答

0

最短的答案是確實修改代理的應用程序源代碼單獨。所以,現在他們使用

var io = require('socket.io')(http, { path: '/proxy/yourApplication'})

這篇文章解決的問題。 https://stackoverflow.com/a/31658307/2633577

但是,這個答案不是最好的,因爲它不是100%透明的託管應用程序。

相關問題