php irc bot,定期向频道发送消息

时间:2013-03-12 05:08:23

标签: php bots irc

我按照一些教程从头开始创建机器人,基本功能正常工作,比如我可以连接,它响应命令,并输出到网页。

我想要的是周期性发送消息,其中包含我从某个卷曲网站获得的频道更新。

$ irc和$ curl只是带有设置的数组,而date('s')就是说返回更新的函数。当然我有工作卷曲功能。 $ irc ['delay']设置为10,所以在sleep(1)中它应该每10秒发送一次更新。

问题是,在第一分钟左右,它每隔10秒发送一次当前秒数,但它不会监听我设置的任何命令。它在第一次初始延迟之后执行命令,我不是它来自的地方 然后,只有当有人在频道上讲话时,它才会发出当前秒数(if条件)。我猜它等待这128个字节?但它确实会立即收听命令。

while(1) {
    while($data = fgets($socket, 128)) {
        echo nl2br($data);
        flush();

        if ($curl['delay'] <= $d) { fputs($socket, "PRIVMSG ".$irc['channel']." :".date('s')."\n"); $d=0; };
        $d+=1;
        sleep(1);

        $ex = explode(' ', $data);
        if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
        $command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
        switch ($command) {
            case ":!say" : fputs($socket, "PRIVMSG ".$ex[2]." :Hello!\n"); break;
            case ":!off" : break 3;
        };
    };
}

我希望它能够响应命令,并定期自动发送拉取数据。但是我不明白它的行为,甚至不确定我想要的是什么可能再用php了



像Ranty建议的那样 没有休息: 它会说出一次日期,然后下次报告至少需要一分钟。如果我说任何命令它会进一步延迟它。

10:39 Moninal我来了 10:39 Moninal 39:24
10:40 Moninal 40:26

10:41 Moninal我来了 10:41 Moninal 41:05
10:41格雷戈斯!说出来 10:41 Moninal你好!
10:41格雷戈斯!说出来 10:41 Moninal你好!
10:42 Moninal 42:51

发送第二条消息后,我第一次在网页上输出,每隔61秒发送一次,而不是10秒。

10:42 Moninal 42:51
10:43 Moninal 43:52
10:44 Moninal 44:53

如果我在内循环中添加break: 对于第一分钟,我每10秒钟收到一次报告,但是在第一分钟结束时所有发送的命令都像以前一样触发。 在那之后命令工作,但每61秒再次报告。

也许这与我的服务器配置有关?

2 个答案:

答案 0 :(得分:0)

我想问题是你在while($data = fgets($socket, 128))循环中拥有所有逻辑。如果您考虑一下,如果聊天中发生了某些事情,您的逻辑就会被执行。所以当你启动脚本时,它执行正常,因为它读取那里的数据(我假设如此),但是在读取数据之后,它只对新数据执行。

现在它只在聊天时打印秒数,因为它等待128个字节的10倍(你的意思是10秒),因为只有当内部while循环条件总是为真时它才会是10秒(如果它每次执行都是秒)。

您可以尝试将一些逻辑移到内部while循环之外。我也为你改变了卷曲时间 - 你让它睡了1秒然后加1到柜台 - 这是不可靠的。您可以简单地比较上次请求的当前时间。

while(1) {
    flush();

    if ($curl['next_request'] <= time()) {
        fputs($socket, "PRIVMSG ".$irc['channel']." :".date('s')."\n");
        $curl['next_request'] = time() + $curl['delay'];
    };

    while($data = fgets($socket, 128)) {
        echo nl2br($data);
        $ex = explode(' ', $data);
        if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
        $command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
        switch ($command) {
            case ":!say" : fputs($socket, "PRIVMSG ".$ex[2]." :Hello!\n"); break;
            case ":!off" : break 3;
        };
    };

    sleep(1);
}

它可能会同时响应所有命令,而不是每秒1次,如果你想改变它,你可以尝试在内部结束时添加一个中断。

答案 1 :(得分:0)

在经历了一天的痛苦之后,我终于找到了愚蠢的理由和解决方案。基本上1分钟延迟的原因是fget命令while($ data = fgets($ socket,128));
解决方法是设置stream_set_timeout($ socket,1);在循环之前。好吧我也最终设置了nginx服务器而不是apache。我不确定这无论如何都有帮助。
另外我想我可以在stream_set_timeout($ socket,1)中设置时间;控制发送消息的最小间隔。

$next=time();
stream_set_timeout($socket,1);
while(1) {

    $data = fgets($socket, 128);
    echo nl2br($data);

    $ex = explode(' ', $data);
    if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
    if (isset($ex[3])) $command = str_replace(array(chr(10), chr(13)), '', $ex[3]);

    switch ($command) {
        case ":!sayit" : 
            $msg = NULL; for ($i = 4; $i < count($ex); $i++) { $msg .= $ex[$i] . ' '; }
            fputs($socket, "PRIVMSG ".$ex[2]." :".$msg."\n"); 
            break;
        case ":!off" :
          fputs($socket, "PRIVMSG ".$irc['channel']." : Bye\n");
          fputs($socket,"QUIT Client Disconnected!\n");
          die('Exited!');
    };

    if ($next <= time()) {
        fputs($socket, "PRIVMSG ".$irc['channel']." :".date('H:i:s')."\n");
        echo "PRIVMSG ".$irc['channel']." :".date('H:i:s')."<br />";
        $next = time() + $curl['delay']; 
    };
    flush(); 
};

好吧,它不包括所有连接设置。这很容易找到怎么做。