2015-04-12 84 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%透明的托管应用程序。

相关问题