8

Joel Berger 发布了这个小程序来启动一个 web 服务器来提供本地文件,它工作得很好:

use Mojolicious::Lite;

@ARGV = qw(daemon);

use Cwd;
app->static->paths->[0] = getcwd;

any '/' => sub {
    shift->render_static('index.html');
    };

app->start;

我预先填充了命令行,@ARGV因为我忘了这样做。当它启动时,它会给出一条消息,告诉你它选择了哪个端口,如果可以的话,使用 3000:

$ perl ~/bin/mojo_cwd
[Fri Mar 29 19:14:09 2013] [info] Listening at "http://*:3000".
Server available at http://127.0.0.1:3000.

我想以编程方式获取该端口,以便测试套件知道在哪里寻找它,而且我不想通过报废输出来做到这一点。我对此的任何实验都没有用,我认为我总是走错方向。似乎它在开始之前不会选择端口,一旦我调用start,它就结束了。

我也不想自己指定端口。

这不是一件紧急的事情。我有一个使用另一个简单的 HTTP 框架的当前解决方案,但如果可以的话,我一直在考虑用 Mojo 替换其中的大部分内容。由于旧的东西仍然有效,这真的只是一件好事,而不是我的方式。

4

2 回答 2

9

You can't, but the daemon command only binds to port 3000 and will not try anything else unless you tell it to. If you're using Test::Mojo you don't need to know the port in advance anyway, for anything else you can always wrap your application in a little Mojo::Server::Daemon script.

use Mojolicious::Lite;
use Mojo::IOLoop;
use Mojo::Server::Daemon;

get '/' => {text => 'Hello World!'};

my $port   = Mojo::IOLoop->generate_port;
my $daemon = Mojo::Server::Daemon->new(
  app    => app,
  listen => ["http://*:$port"]
);
$daemon->run;
于 2013-04-01T11:47:47.330 回答
7

使用--listen您为应用指定收听位置的参数:

use Mojolicious::Lite;

@ARGV = qw(daemon --listen http://*:5000);

use Cwd;
app->static->paths->[0] = getcwd;

any '/' => sub {
    shift->render_static('index.html');
    };

app->start;

您可以通过以下方式访问应用程序中的端口号$self->tx->local_port

#!/usr/bin/env perl
use Mojolicious::Lite;

@ARGV = qw(daemon --listen http://*:5000);

use Cwd;
app->static->paths->[0] = getcwd;

any '/' => sub {
    my $self = shift;

    $self->render_text('port: '. $self->tx->local_port);
    };

app->start if $ENV{MOJO_MODE} ne 'test';

1;

我喜欢测试Mojolicious应用程序,Test::Mojo因为您可以访问正在运行的应用程序,例如,在文件中t/test_mojo.t

use strict;
use warnings;

use feature 'say';

use Test::More;
use Test::Mojo;

$ENV{MOJO_MODE} = 'test';

require "$FindBin::Bin/../test_mojo.pl";

my $t = Test::Mojo->new;
$t->get_ok('/')->status_is(200)->content_is('port: '.$t->tx->remote_port);

say 'local port: '. $t->tx->local_port; #as seen from the user-agent's perspective
say 'remote port:'. $t->tx->remote_port;
done_testing();

我不确定我是否正确理解了您要完成的工作,但我希望这对您有所帮助。

于 2013-03-31T06:47:25.897 回答