如何在app.psgi中获取关于自己的信息?

How to get information about itself in app.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;

如何发现运行nig服务器的一些信息?例如,当 运行 时 app.psgi 为:

plackup -p 6000

将设置并打印 $port- 6000。

$app 里面很容易,因为我可以访问 $env。但是我想在 $port 之前 $app 被调用,例如上面的示例在每个请求时打印端口 - 但我想在 $app 开始之前获得 $port 一次 运行ning.

编辑

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

我想获取监听端口。

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

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

我现在还意识到,将 plackup 命令本身包装到一些代码中要容易得多,例如 runserver.pl - 并且知道我将用于 [=50= 的端口] plackup 命令。 ;)

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

在当前的 PSGI 规范中没有 API 来实现这一点,这是设计使然。正如已经指出的那样,侦听端口可以是多个端口甚至是 unix 套接字。该应用不需要也不应该知道 运行ning 环境。

为了您的实际动机,即通过 bonjour 宣传绑定 address/port:

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

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