2010-03-18 43 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

我接手博特:: BasicBot的maintainership,並作爲版本0.82,你可以用$bot->shutdown($quit_message)正確關閉它。

0

從看Bot :: BasicBot的文檔和源代碼,我無法找到一個優雅的方式來關閉它。正如您演示的那樣,撥打$bot->shutdown()(實際上發送shutdown事件到POE::Component::IRC)只會導致Bot::BasicBot重新連接(順便說一句,與$bot->quit()相同)。

用戶遇到的這個和其他限制使我推薦直接使用POE::Component::IRC。它現在有許多插件用於Bot::BasicBot提供的功能,當創建Bot::BasicBot時丟失了這些功能。雖然您可能需要輸入更多信息才能使基本的機器人啓動並運行,但您擁有更多的靈活性。下面是您的示例中的一個bot,不使用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 2010-07-16 02:05:18

+0

它們如何比POE :: Component :: IRC更高性能?它在哪裏有太多複雜的魔法?如果你有這方面的有用信息,我可能會在這方面改進POE :: Component :: IRC。 – Hinrik 2010-07-20 17:42:09

+0

這不是關於PoCo-IRC,而是關於POE,API很複雜(有內核,循環,過濾器,會話和事件)需要大量的樣板才能工作(比較Poco-IRC,AE-IRC的大小和Net-Async-IRC的模塊)。至於性能,或許這歸結爲POE的複雜性,對於有用的基準,請參閱CPAN上的Starman,基準部分,Twiggy是AnyEvent Plack服務器,Corona是Coro(AnyEvent + Coroutines)Plack服務器。 – MkV 2010-07-20 21:59:28