How do I correctly shutdown a Bot::BasicBot bot (based on POE::Component::IRC)?
This is a sample script. When I hit Ctrl+C, the bot quits IRC but it reconnects back after some time. How do I shut down the bot correctly?
#!/开发者_Go百科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');
}
I've taken over maintainership of Bot::BasicBot, and as of version 0.82, you can shut it down properly with $bot->shutdown($quit_message).
From looking at Bot::BasicBot's documentation and source code, I can't find a graceful way to shut it down. As you demonstrated, calling $bot->shutdown() (which actually sends a shutdown event to POE::Component::IRC) will just cause Bot::BasicBot to reconnect (same with $bot->quit() by the way).
This and other limitations users have run into have caused me to recommend using POE::Component::IRC directly. It has many plugins nowadays for features provided by Bot::BasicBot which were missing when Bot::BasicBot was created. While you may have to type a bit more to get a basic bot up and running, you have much more flexibility. Below is a bot like the one in your example, without using Bot::BasicBot. It will send a quit message to the IRC server when you press CTRL+C, wait until it has been disconnected, then exit:
#!/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};
}
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论