如何为 Net::IRC 机器人设置互联网连接检测器



我有一个用Perl编写的IRC机器人,使用已弃用的,未记录的和不受欢迎的Net::IRC库。不过,它运行得很好...除非连接断开。在他们实现对重新连接的支持之前,该库似乎已停止更新。显而易见的解决方案是重写整个机器人以利用库的后继者,但不幸的是,这需要重写整个机器人。

所以我对解决方法感兴趣。

我目前的设置被监督配置为在进程意外退出时重新启动机器人,并在互联网连接丢失时终止进程的 cron 作业。

这不像我希望的那样工作,因为机器人似乎无法检测到它由于互联网中断而失去连接。它会很高兴地继续运行,什么都不做,假装仍然连接到 IRC 服务器。

我有以下代码作为主程序循环:

while (1) {
    $irc->do_one_loop;
    # can add stuff here
}

我希望它做的是:
a( 检测到互联网已中断,
b( 等到互联网上线,
c(退出脚本,以便主管可以复活它。

还有其他更好的方法吗?

编辑:由于未知原因,脚本内方法不起作用。我正在尝试制作一个单独的脚本来解决它。

#!/usr/bin/perl
use Net::Ping::External;
while (1) { 
    while (Net::Ping::External::ping(host => "8.8.8.8")) { sleep 5; }
    sleep 5 until Net::Ping::External::ping(host => "8.8.8.8");
    system("sudo kill `pgrep -f 'perl painbot.pl'`");
}

假设do_one_loop不会挂起(如果需要,可能需要添加一些alarm(,您需要主动轮询某些内容以判断网络是否启动。像这样的事情应该在失败后每 5 秒执行一次 ping 操作,直到您收到响应,然后退出。

use Net::Ping::External;
sub connectionCheck {
    return if Net::Ping::External::ping(host => "8.8.8.8");
    sleep 5 until Net::Ping::External::ping(host => "8.8.8.8");
    exit;
}

编辑:由于do_one_loop似乎确实挂起了,因此您需要一些方法来包装超时。时间量取决于您期望它运行多长时间,以及如果它变得无响应,您愿意等待多长时间。执行此操作的一种简单方法是使用 alarm(假设您不在 Windows 上(:

local $SIG{'ALRM'} = sub { die "Timeout" };
alarm 30; # 30 seconds
eval {
    $irc->do_one_loop;
    alarm 0;
};

Net::IRC主循环支持超时和计划事件。

尝试这样的事情(我还没有测试过它,距离我上次使用该模块已经 7 年了......

# connect to IRC, add event handlers, etc.
$time_of_last_ping = $time_of_last_pong = time;
$irc->timeout(30);
# Can't handle PONG in Net::IRC (!), so handle "No origin specified" error
# (this may not work for you; you may rather do this some other way)
$conn->add_handler(409, sub { $time_of_last_pong = time });
while (1) {
    $irc->do_one_loop;
    # check internet connection: send PING to server
    if ( time-$time_of_last_ping > 30 ) {
        $conn->sl("PING"); # Should be "PING anything"
        $time_of_last_ping = time;
    }
    break if time-$time_of_last_pong > 90;
}

相关内容

最新更新