От взгляда на Бот :: Документация и исходный код BasicBot, я не могу найти изящный способ закрыть его. Как вы показали, вызов $bot->shutdown()
(который фактически отправляет событие shutdown
на POE::Component::IRC
) просто приведет к восстановлению соединения Bot::BasicBot
(то же самое с $bot->quit()
).
Этот и другие ограничения, с которыми сталкиваются пользователи, заставили меня рекомендовать напрямую использовать POE::Component::IRC
. В настоящее время у него много плагинов для функций, предоставляемых Bot::BasicBot
, которые отсутствовали при создании Bot::BasicBot
. Хотя вам, возможно, придется набрать немного больше, чтобы получить базовый бот и работать, у вас гораздо больше гибкости. Ниже приведен бот, подобный приведенному в вашем примере, без использования Bot::BasicBot
. Он будет посылать сообщения о выходе на сервер IRC при нажатии клавиши CTRL + C, подождите, пока он не был отключен, то выход:
#!/usr/bin/env perl
use strict;
use warnings;
use POE;
use POE::Component::IRC::State;
use POE::Component::IRC::Common qw(parse_user);
use POE::Component::IRC::Plugin::Connector;
use POE::Component::IRC::Plugin::AutoJoin;
# create our session
POE::Session->create(
package_states => [
# event handlers
(__PACKAGE__) => [qw(_start int irc_join irc_disconnected)]
]
);
# start the event loop
POE::Kernel->run();
# session start handler
sub _start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
# handle CTRL+C
$kernel->sig(INT => 'int');
# create bot object
my $irc = POE::Component::IRC::State->spawn(
server => 'irc.freenode.net',
nick => 'basic123bot',
debug => 1,
);
# save $irc in our session's storage heap
$heap->{irc} = $irc;
# handle reconnects
$irc->plugin_add('Connector', POE::Component::IRC::Plugin::Connector->new());
# handle channel joining
$irc->plugin_add('AutoJoin', POE::Component::IRC::Plugin::AutoJoin->new(
Channels => ['#foo123bar'],
));
# connect to IRC
$irc->yield('connect');
}
# interrupt signal handler
sub int {
my ($kernel, $heap) = @_[KERNEL, HEAP];
$heap->{irc}->yield('quit', 'Quitting, bye!');
$heap->{shutting_down} = 1;
$kernel->sig_handled();
}
# join handler
sub irc_join {
my ($who, $chan) = @_[ARG0, ARG1];
my $irc = $_[HEAP]->{irc};
my ($nick, $user, $host) = parse_user($who);
if ($nick eq $irc->nick_name()) {
# say hello to channel members
$irc->yield('privmsg', $chan, 'Hello everybody');
}
}
# disconnect handler
sub irc_disconnected {
my ($heap) = $_[HEAP];
# shut down if we disconnected voluntarily
$heap->{irc}->yield('shutdown') if $heap->{shutting_down};
}
Если вы собираетесь обойтись без Bot :: BasicBot, можете также взглянуть на AnyEvent :: IRC или Net :: Async :: IRC, которые кажутся намного более результативными и имеют менее сложную магию. – MkV
Как они более эффективны, чем POE :: Component :: IRC? Где у него слишком сложная магия? Если у вас есть полезная информация об этом, я мог бы улучшить POE :: Component :: IRC в этом отношении. – Hinrik
Речь идет не о PoCo-IRC, а о POE, API сложный (с ядрами, петлями, фильтрами, сеансами и событиями) требуется много шаблонов для работы (сравните размер Poco-IRC, AE-IRC и модули Net-Async-IRC). Что касается производительности, возможно, это сводится к сложности POE, поскольку полезный бенчмарк см. В статье «Starman on CPAN», в разделе «Тесты», Twiggy - это сервер AnyEvent Plack, а Corona - сервер Plo Coro (AnyEvent + Coroutines). – MkV