【问题标题】:How do I correctly shutdown a Bot::BasicBot bot (based on POE::Component::IRC)?如何正确关闭 Bot::BasicBot 机器人(基于 POE::Component::IRC)?
【发布时间】:2011-01-29 02:33:30
【问题描述】:

这是一个示例脚本。当我按下 Ctrl+C 时,机器人会退出 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');
}

【问题讨论】:

    标签: perl irc bots poe


    【解决方案1】:

    我已经接管了 Bot::BasicBot 的维护工作,从 0.82 版开始,您可以使用 $bot->shutdown($quit_message) 正确关闭它。

    【讨论】:

      【解决方案2】:

      通过查看 Bot::BasicBot 的文档和源代码,我找不到关闭它的优雅方法。正如您所演示的,调用$bot->shutdown()(实际上向POE::Component::IRC 发送shutdown 事件)只会导致Bot::BasicBot 重新连接(顺便说一句,与$bot->quit() 相同)。

      用户遇到的这个和其他限制导致我建议直接使用POE::Component::IRC。现在它有许多插件,用于Bot::BasicBot 提供的功能,而Bot::BasicBot 创建时这些功能缺失。虽然您可能需要输入更多内容才能启动和运行基本机器人,但您拥有更多的灵活性。下面是一个类似于您示例中的机器人,但未使用 Bot::BasicBot。当你按下CTRL+C时,它会向IRC服务器发送一条退出消息,等待它断开连接,然后退出:

      #!/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,它们似乎性能更高,魔力更简单。
      • 它们比 POE::Component::IRC 性能如何?哪里有太多复杂的魔法?如果你有这方面的有用信息,我也许可以在这方面改进 POE::Component::IRC。
      • 这不是关于 PoCo-IRC,而是关于 POE,API 很复杂(包含内核、循环、过滤器、会话和事件)需要大量样板才能工作(比较Poco-IRC、AE-IRC 和 Net-Async-IRC 的模块)。至于性能,这可能归结为 POE 的复杂性,有关有用的基准,请参阅 Starman on CPAN,基准部分,Twiggy 是 AnyEvent Plack 服务器,Corona 是 Coro (AnyEvent + Coroutines) Plack 服务器。
      • 通过查看 AnyEvent-IRC 和 Net-Async-IRC,我的印象是它们的较小尺寸与所使用的事件模型几乎没有关系。 POE-Component-IRC 的核心是 IRC.pm 中大约 1600 行代码,其中大部分处理将 IRC 协议映射到对用户有用的 API。发行版中的几乎所有其他内容都包含在此之上实现可选功能的子类和插件,在您提到的其他发行版中几乎没有一个具有可比性的部分。它们更小主要是因为它们的功能更少。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      相关资源
      最近更新 更多