node.js – Phusion Passenger Error:多次调用http.Server.listen()

我想用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.

比我在谷歌组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);

解决方法:

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');

如果乘客注意到你有多个听(‘乘客’)电话,它会抱怨.你只能有一个.

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

Express.js的例子

这是一个使用Express框架的完整示例.您必须将“乘客”传递给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();

相关文章

Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一...
本地项目配置 1 复制 luffy/settings/dev.py为prop.py 修改l...
nginx不仅可以隐藏版本信息,还支持自定义web服务器信息 先看...
一 、此次漏洞分析 1 nginx HTTP/2漏洞 [nginx-announce] ng...
###进入nginx 目录cd /usr/local/nginx###递归显示 2 级目录...
在cmd命令窗口输入下面命令进行查看 tasklist /fi "ima...