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

Perl 如何在app.psgi中获取有关自身的信息?,perl,plack,psgi,Perl,Plack,Psgi,拥有任何基于PSGI的应用程序,例如,类似以下app.PSGIsnippet 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 = s

拥有任何基于PSGI的应用程序,例如,类似以下
app.PSGI
snippet

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
as时:

plackup -p 6000
将设置并打印
$port
-6000

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

编辑 是的,我必须意识到服务器可能会监听更多的端口,确切的端口是在请求到达某些端口时定义的

我要获取侦听端口

但是根据评论和回答,这里可能没有任何统一的API用于不同的服务器实现(Starman、Twiggy)来获取侦听端口

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


现在我还意识到,将
plackup
命令本身包装成一些代码要容易得多,例如
runserver.pl
,并且知道运行
plackup
命令时要使用的端口

就像@Borodin已经指出的那样,在
$app
-coderef之外没有端口。但如果您使用符合PSGI的服务器运行
$app
,则此服务器正在侦听某个端口。如果你需要在应用程序本身之前知道这个端口,你必须用你的自定义代码包装它,然后你可以用它做一些事情

在当前的PSGI规范中,设计上没有API可以实现这一点。如前所述,侦听端口可以是多个端口,甚至可以是unix套接字。应用程序不需要也不应该知道运行环境

出于您的实际动机,即通过bonjour公布绑定地址/端口:

a) 您可以编写引导脚本,然后使用Plack::Runner模块运行plackup内核。实际上,这正是App::HTTPThis所做的(它也做了“你好”一点)


b) Plack::Runner和一些PSGI处理程序支持
server\u ready
hook,但遗憾的是,它们没有很好的文档记录,允许您传递代码引用,以便在启动时获取绑定主机和端口。

我不明白。当传入HTTP请求到达时,调用
$app
子例程。在此之前,没有端口,因为它是requestAFAIK的一部分,所以中间件包装了PSGI应用程序(它们看起来也像一个应用程序),所以当请求到达时就会触发它们。不是吗?如何帮助我编写一个中间件来获取(正如你正确地说的)侦听端口?@kobame,我不清楚你的意图,所以我建议,如果你出于某种原因需要在请求到达应用程序之前知道端口信息,中间件(是的,基本上是其他PSGI应用程序)可能是你的最佳选择。答案的每个字节都非常有用。
App-HTTPThis
是一个优秀的学习材料。非常感谢你!