如何在app.psgi中获取有关自身的信息?

时间:2015-03-27 21:09:09

标签: perl plack psgi

拥有任何基于PSGI的应用,例如如下面的app.psgi代码段

use 5.016;
use warnings;
use Data::Dumper;

#WHAT TO DO HERE to get the $port?
my $port = $ENV{SERVER_PORT} // "undefined"; 
print STDERR "my port is: $port\n"; #says "undefined"

my $app = sub {
    my $env = shift;
    printf STDERR "Port from the app is: $env->{SERVER_PORT}\n";
    return [
        200,
        ['Content-Type' => 'text/plain'],
        [ "hello world!"],
    ];
};

$app;

如何发现有关runnig服务器的一些信息?例如,运行app.psgi时:

plackup -p 6000

将设置&打印$port - 6000。

$app内部,这很容易,因为我可以访问$env。但我希望在调用$port 之前获取$app ,例如以上示例在每个请求中打印端口 - 但我希望在$port开始运行之前获取$app一次。

修改

是的,我必须知道,例如服务器可以侦听更多端口,并且在请求到达某个端口时定义了确切的端口。

我想获得监听端口。

但基于评论和回答可能在这里不是任何统一的API到不同的服务器实现(Starman,Twiggy)来获得监听端口。

问题背后的真正原因是我想向Bonjour(Zeroconf)宣传这些应用程序。 (我还不知道如何(但是),但有必要知道应用程序正在侦听哪个端口。)

现在我意识到将plackup命令本身更容易包装到某些代码中,例如runserver.pl - 并且将知道端口将用于运行{{1}的内容命令。 ;)

2 个答案:

答案 0 :(得分:4)

根据设计,目前的PSGI规范中没有API可以获得此功能。正如已经指出的,侦听端口可以是多个端口甚至是unix套接字。该应用程序并不需要知道运行环境。

根据您的实际动机,即通过bonjour宣传绑定地址/端口:

a)您可以编写启动脚本,然后使用Plack :: Runner模块运行plackup核心。实际上这正是App :: HTTPThis所做的(它也是bonjour位)https://metacpan.org/release/App-HTTPThis

b)Plack :: Runner和一些PSGI处理程序支持server_ready挂钩,遗憾的是没有很好地记录,这允许您传递代码引用以获取绑定主机和端口启动时间。

答案 1 :(得分:0)

就像@Borodin已经指出的那样,$app之外没有端口 - coderef。但是,如果您使用符合PSGI标准的服务器运行$app,则此服务器正在侦听某个端口。如果您需要在应用程序本身之前知道此端口,则必须使用自定义middleware对其进行包装,然后您可以对其进行操作。