使用sleep()会延迟所有输出

时间:2014-02-19 08:08:29

标签: php

我使用名为Philip(https://github.com/epochblue/philip)的PHP bot框架构建了一个IRC bot。当任何人将命令!hello发送到聊天中时,机器人应该在通道中说“你好......”,等待45秒,说“foo”,等待15秒,然后说“bar”(I知道这没有任何意义,只是试图让这个代码工作)。

这是我到目前为止尝试过的代码:

尝试#1

$bot->onChannel('/^!hello$/', function($event) {
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "hello..."));
    $now = time();
    while ($now + 45 > time()) {

    }
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "foo"));
    while ($now + 60 > time()) {

    }
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "bar"));
});

尝试#2

$bot->onChannel('/^!hello$/', function($event) {
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "hello..."));
    sleep(45);
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "foo"));
    sleep(15);
    $event->addResponse(Response::msg($event->getRequest()->getSource(), "bar"));
});

在这两次尝试中,机器人将等待整整60秒,然后输出任何东西。因此,不是发送一条消息,然后等待,然后发送另一条消息,然后等待,然后发送第三条消息,它只等待所有60秒然后发送消息。

我想知道如何按照我的意愿让它工作吗?

由于

2 个答案:

答案 0 :(得分:0)

睡眠会冻结您当前所在的主题。 您应该使用“pthreads”在新线程上发送消息(并在那里睡眠导致主线程不冻结),或者您应该使用计时器。

答案 1 :(得分:0)

如果您查看fwrite()文档,则会有以下内容:

  

注意:   写入网络流可能在写入整个字符串之前结束。可以检查fwrite()的返回值:

<?php
function fwrite_stream($fp, $string) {
    for ($written = 0; $written < strlen($string); $written += $fwrite) {
        $fwrite = fwrite($fp, substr($string, $written));
        if ($fwrite === false) {
            return $written;
        }
    }
    return $written;
}

因此,在Phillip::send方法中,您可以使用类似的解决方案来保存方法,直到套接字的fwrite完成并返回成功布尔值等。