Socket.io 在收到握手响应之前关闭 [ECONNRESET] 在代理之后
Socket.io closed before receiving a handshake response [ECONNRESET] after a proxy
我正在为 node.js 应用程序编写任务管理器。这些应用程序在任意端口打开,因此,为了访问它们,我想伪造它们的根目录
像这样的 URL:
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");
}
});
它适用于大多数应用程序,但在使用 socket.io 打开应用程序时会提示:
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)
因为它是一个 "proxy" 伪造的应用程序根目录,我可能无法单独修改它们的源代码,它们应该按预期工作。在正确的端口(本例中为 3000)打开它们时,它们不会显示任何错误。
提前致谢!
最简单的答案确实是单独修改代理应用程序的源代码。所以现在他们使用
var io = require('socket.io')(http, { path: '/proxy/yourApplication'})
这 post 解决了这个问题。
但是这个答案并不是最好的,因为它对托管应用不是 100% 透明的。
我正在为 node.js 应用程序编写任务管理器。这些应用程序在任意端口打开,因此,为了访问它们,我想伪造它们的根目录 像这样的 URL:
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");
}
});
它适用于大多数应用程序,但在使用 socket.io 打开应用程序时会提示:
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)
因为它是一个 "proxy" 伪造的应用程序根目录,我可能无法单独修改它们的源代码,它们应该按预期工作。在正确的端口(本例中为 3000)打开它们时,它们不会显示任何错误。
提前致谢!
最简单的答案确实是单独修改代理应用程序的源代码。所以现在他们使用
var io = require('socket.io')(http, { path: '/proxy/yourApplication'})
这 post 解决了这个问题。
但是这个答案并不是最好的,因为它对托管应用不是 100% 透明的。