2010-03-18 4 views
3

Это пример сценария. Когда я нажимаю Ctrl + C, бот выходит из IRC, но через некоторое время он снова подключается. Как правильно закрыть бот?Как правильно закрыть бот Bot :: BasicBot (на основе POE :: Component :: IRC)?

#!/usr/bin/perl 

package main; 

my $bot = Perlbot->new (server => 'irc.dal.net'); 

$SIG{'INT'} = 'Handler'; 
$SIG{'TERM'} = 'Handler'; 

sub Handler { 
print "\nShutting down bot...\n"; 
$bot->shutdown('Killed.'); 
}; 

$bot->run; 

package Perlbot; 
use base qw(Bot::BasicBot); 

sub connected { 
my $self = shift; 
$self->join('#codetestchan'); 
} 

ответ

2

Я взял над maintainership СЭП :: BasicBot, и в версии 0,82, вы можете правильно закрыть его с помощью $bot->shutdown($quit_message).

0

От взгляда на Бот :: Документация и исходный код 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}; 
} 
+0

Если вы собираетесь обойтись без Bot :: BasicBot, можете также взглянуть на AnyEvent :: IRC или Net :: Async :: IRC, которые кажутся намного более результативными и имеют менее сложную магию. – MkV

+0

Как они более эффективны, чем POE :: Component :: IRC? Где у него слишком сложная магия? Если у вас есть полезная информация об этом, я мог бы улучшить POE :: Component :: IRC в этом отношении. – Hinrik

+0

Речь идет не о PoCo-IRC, а о POE, API сложный (с ядрами, петлями, фильтрами, сеансами и событиями) требуется много шаблонов для работы (сравните размер Poco-IRC, AE-IRC и модули Net-Async-IRC). Что касается производительности, возможно, это сводится к сложности POE, поскольку полезный бенчмарк см. В статье «Starman on CPAN», в разделе «Тесты», Twiggy - это сервер AnyEvent Plack, а Corona - сервер Plo Coro (AnyEvent + Coroutines). – MkV