3 Stimmen

Wie schalte ich einen Bot::BasicBot (basierend auf POE::Component::IRC) korrekt ab?

Dies ist ein Beispielskript. Wenn ich Strg+C drücke, beendet der Bot das IRC, verbindet sich aber nach einiger Zeit wieder zurück. Wie beende ich den Bot richtig?

#!/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');
}

2voto

Hinrik Punkte 793

Ich habe die Wartung von Bot::BasicBot übernommen, und seit Version 0.82 kann man ihn mit $bot->shutdown($quit_message) .

0voto

Hinrik Punkte 793

Wenn ich mir die Dokumentation und den Quellcode von Bot::BasicBot ansehe, kann ich keinen eleganten Weg finden, um ihn abzuschalten. Wie Sie gezeigt haben, ist der Aufruf von $bot->shutdown() (die tatsächlich eine shutdown Ereignis zu POE::Component::IRC ) wird nur dazu führen, dass Bot::BasicBot um die Verbindung wiederherzustellen (dasselbe gilt für $bot->quit() nebenbei bemerkt).

Diese und andere Einschränkungen, auf die Benutzer gestoßen sind, haben mich veranlasst, die Verwendung von POE::Component::IRC direkt. Heutzutage gibt es viele Plugins für Funktionen, die von Bot::BasicBot die fehlten, als Bot::BasicBot geschaffen wurde. Sie müssen zwar etwas mehr tippen, um einen einfachen Bot zum Laufen zu bringen, aber Sie haben viel mehr Flexibilität. Nachfolgend sehen Sie einen Bot wie in Ihrem Beispiel, ohne die Verwendung von Bot::BasicBot . Es sendet eine Beendigungsnachricht an den IRC-Server, wenn Sie STRG+C drücken, und wartet, bis die Verbindung getrennt wurde:

#!/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 Stimmen

Wenn Sie auf Bot::BasicBot verzichten wollen, können Sie sich auch AnyEvent::IRC oder Net::Async::IRC ansehen, die viel leistungsfähiger zu sein scheinen und weniger komplizierte Magie haben.

0 Stimmen

Inwiefern sind sie leistungsfähiger als POE::Component::IRC? Wo hat es zu viel komplizierte Magie? Wenn Sie nützliche Informationen dazu haben, kann ich POE::Component::IRC vielleicht in dieser Hinsicht verbessern.

0 Stimmen

Es geht nicht wirklich um PoCo-IRC, sondern um POE, die API ist kompliziert (mit Kernels, Schleifen, Filtern, Sessions und Events) und erfordert eine Menge Boilerplate, um zu funktionieren (vergleiche die Größe der Module von Poco-IRC, AE-IRC und Net-Async-IRC). Was die Leistung angeht, so liegt das vielleicht an der Komplexität von POE, für einen nützlichen Benchmark siehe Starman auf CPAN, Abschnitt Benchmarks, Twiggy ist der AnyEvent Plack Server, und Corona ist der Coro (AnyEvent + Coroutines) Plack Server.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X