问题
I have a simple IRC bot using POE::Component::IRC. It was only when I was attempting to make it gracefully handle SIGINT by quitting with a useful message that I found that I can't make it quit with any message at all, ever whether as part of a signal handler or just a normal call to quit.
Let's say I've got the session created something like this:
POE::Session->create( inline_states => { irc_disconnected => \&bot_reconnect, irc_error => \&bot_reconnect, irc_socketerr => \&bot_reconnect, connect => \&bot_reconnect, . . . }, );
And bot_reconnect
is just going to connect back to IRC should
anything go wrong:
sub bot_reconnect { my ($kernel, $heap) = @_[KERNEL, HEAP]; if (1 == $heap->{shutting_down}) { $heap->{irc}->yield(shutdown => 'blah'); } else { some_log_func("Reconnecting in 60 secs"); $kernel-delay(connect => 60); } }
If, anywhere else in the code I set shutting_down
to 1 and tell it
to quit (e.g. $irc->yield(quit => "bye!")
) it immediately quits
IRC with either no quit message ("Client Quit", the ircd displays)
or else with "Remote host closed the connection".
It then receives the irc_disconnected
event which takes it to
bot_reconnect
above, where shutdown
appears to do nothing at
all. In fact if I don't explicitly exit 0
after that shutdown
then the process just stays in limbo with no connect to IRC any
more.
Is that what is supposed to happen?
I found:
http://search.cpan.org/~bingos/POE-Component-IRC-6.79/lib/POE/Component/IRC/Cookbook/Disconnecting.pod
which says to use shutdown
. As you can see, I tried that, and it
doesn't seem to work.
I also found some sample code for this in another question:
How do I correctly shutdown a Bot::BasicBot bot (based on POE::Component::IRC)?
However that is very similar to what I have now, and it also doesn't seem to behave any differently.
The package version of libpoe-component-irc-perl
is 6.78+dfsg-1 so
that should be greater than 6.50 as the above URL says.
Any ideas?
回答1:
It turns out that this is the "fault" of the ircd.
I also reported this as a bug to POE::Component::IRC's request tracker, and Hinrik responded, asking me if I was trying to do this on Freenode. Freenode's ircd has a feature where it ignores your quit message if you haven't been connected for very long.
I wasn't trying to do it on Freenode, but it turns out that the network I was doing it on does do this. They're using Charybdis:
https://github.com/atheme/charybdis/blob/master/modules/core/m_quit.c#L75
来源:https://stackoverflow.com/questions/12884311/how-do-i-issue-a-quit-message-with-perls-poecomponentirc