Phusion Passenger Error:http.Server.listen()被多次调用

时间:2013-12-17 21:39:37

标签: node.js nginx passenger http-proxy

我想用nginx在phusion乘客上执行一个简单的node-http-proxy示例。 您可以在https://github.com/nodejitsu/node-http-proxy上找到此示例代码。

var http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server
//
httpProxy.createServer(9000, 'localhost').listen(8000);

//
// Create your target server
//
http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
  res.end();
}).listen(9000);

如果我执行此代码,则会收到以下错误。

App 28096 stderr: /usr/share/passenger/helper-scripts/node-loader.js:157
App 28096 stderr:       throw new Error("http.Server.listen() was called more than once, which " +
App 28096 stderr:             ^
App 28096 stderr: Error: http.Server.listen() was called more than once, which is not allowed because Phusion Passenger is in auto-install mode. This means that the first http.Server object for which listen() is called, is automatically installed as the Phusion Passenger request handler. If you want to create and listen on multiple http.Server object then you should disable auto-install mode.

比我在Google群组https://groups.google.com/forum/#!topic/phusion-passenger/sZ4SjU8ypwc上找到帖子并添加

PhusionPassenger.configure({ autoInstall: false });

在我第一次调用“createServer(...)。listen(port)”之前。

下一步是使用值'passenger'替换listen-method的port参数的值。但我没有成功。有没有人设法让这个运行?

---我的解决方案---

感谢Hongli的建议“接下来,您需要修改一个(且只有一个)调用...”。这解决了我的问题。

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

if (typeof(PhusionPassenger) != 'undefined') {
  PhusionPassenger.configure({ autoInstall: false });
}

httpProxy.createServer(9000, 'localhost').listen('passenger');

var target_server = http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
  res.end();
}).listen(9000);

2 个答案:

答案 0 :(得分:3)

2015年7月28日更新:此答案现已纳入官方Passenger文档。有关最新答案,请参阅https://www.phusionpassenger.com/library/indepth/nodejs/reverse_port_binding.html


Phusion Passenger作者在这里。首先,让我解释一下这个错误发生的原因。

正如the Node.js tutorial中所述,Phusion Passenger inverses port binding通过挂钩http.Server.listen()。如果有多个listen(),则Passenger不知道用于接收请求的http.Server对象,因此会抛出此错误。

要解决此问题,您需要告诉Passenger“我想明确指定哪个http.Server用于接收请求”。这分两步完成。首先,您必须在程序中尽早调用以下代码:

if (typeof(PhusionPassenger) != 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
}

接下来,您需要修改http.Server.listen()的一个(且仅一个)调用,并使其通过'passenger'的参数:

server.listen('passenger');

如果Passenger注意到您有多个listen('passenger')来电,则会抱怨。你只能有一个。

自Phusion Passenger 4.0.52起,你也可以传递'/passenger'作为参数。这是为了Hapi.js的支持(见下文)。

Express.js示例

这是一个使用Express框架的完整示例。您必须将'passenger'传递给Express的listen()电话。

if (typeof(PhusionPassenger) != 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
}

var express = require('express');
var app = express();
app.get('/', function(req, res){
    var body = 'Hello World';
    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('Content-Length', body.length);
    res.end(body);
});

if (typeof(PhusionPassenger) != 'undefined') {
    app.listen('passenger');
} else {
    app.listen(3000);
}

Hapi.js示例

使用Hapi.js时,必须将'/passenger'(不是'passenger')传递给Hapi的服务器构造函数。这将导致Hapi尝试侦听Unix域套接字,这允许Phusion Passenger的覆盖启动。如果你没有传递那个初始斜杠,那么Hapi将尝试将该参数视为TCP / IP域名,而Hapi将失败并出现错误。

if (typeof(PhusionPassenger) != 'undefined') {
    PhusionPassenger.configure({ autoInstall: false });
}

var Hapi = require('hapi');
var server;

if (typeof(PhusionPassenger) != 'undefined') {
    // Requires Phusion Passenger >= 4.0.52!
    server = new Hapi.Server('/passenger');
} else {
    server = new Hapi.Server('localhost', 3000);
}

server.route({
    method: 'GET',
    path: '/hello',
    handler: function (request, reply) {
        reply('hello world');
    }
});

server.start();

答案 1 :(得分:0)

Hapi.js v8.x.x

hapi版本> v6.x.x使用此表单:



// http://stackoverflow.com/questions/20645231/phusion-passenger-error-http-server-listen-was-called-more-than-once/20645549
if ('undefined' !== typeof(PhusionPassenger)) {
  PhusionPassenger.configure({autoInstall: false});
}

var Hapi   = require('hapi'),
    server = new Hapi.Server(settings.server);

if ('undefined' !== typeof(PhusionPassenger)) {// Requires Phusion Passenger >= 4.0.52!
  server.connection({port: '/passenger'});
} else {
  server.connection({port: 3000, host: 'localhost'});
}

server.route({
    method: 'GET',
    path: '/hello',
    handler: function (request, reply) {
        reply('hello world');
    }
});

// Start the server
server.start(function serverStart() {
  server.log(['server'], 'Server@' + settings.hostname + ' (' + server.info.host + ')' + ' started at port ' + server.info.port);
});