Как я могу получить порт, который выбирает Mojolicious::Lite?

Джоэл Бергер опубликовал эту небольшую программу для запуска веб-сервера для обслуживания локальных файлов, и она прекрасно работает:

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, если смогу. Поскольку старые вещи все еще работают, это действительно просто нечто хорошее, а не что-то на моем пути.

2 ответа

Решение

Вы не можете, но daemon Команда привязывается только к порту 3000 и не будет пробовать ничего другого, пока вы не скажете это. Если вы используете Test::Mojo в любом случае вам не нужно заранее знать порт, иначе вы всегда можете немного обернуть свое приложение Mojo::Server::Daemon скрипт.

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;

С --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();

Я не уверен, что правильно понял, что вы пытаетесь достичь, но я надеюсь, что это поможет вам.

Другие вопросы по тегам