2014-02-19 4 views
1

Я построил бот IRC, используя фреймворк PHP bot под названием Philip (https://github.com/epochblue/philip). Когда команда !hello отправляется в чат кому-либо, бот должен сказать «привет ...» в канал, подождать 45 секунд, сказать «foo», подождать 15 секунд, а затем сказать «бар» (я знаю, что doesn ' t имеет смысл, просто пытается заставить этот код работать).Использование sleep() задерживает весь вывод

Вот код, который я пытался до сих пор:

Попытка # 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

Попробуйте http://www.php.net/flush после каждого сообщения – Reeno

+1

Я не знаю рамки, но смотрю на код (https://github.com/epochblue/philip/blob/master/ src/Philip/Philip.php) похоже, что вы хотите отправлять отдельные ответы с помощью метода 'send()' («На самом деле переместите данные обратно в сокет (giggity)».). – CompuChip

+0

@ Рино просто попробовал это. Кажется, не работает. – 585connor

ответ

0

Сон замерзает нить вы в данный момент. Вы должны либо сделать отправки сообщений в новом потоке (и спать там вызывая основной поток не замораживать) с помощью «Pthreads» или вы должны использовать таймер.

+0

Это все еще не объясняет (по крайней мере, так я понимаю), почему первое сообщение, отправленное до вызова sleep(), не отображается до последнего сна(). Есть ли успешный ответ, который он должен ждать перед сном? – Anthony

+0

При отправке сообщения он будет фактически добавлен в «буфер». Поскольку вы вызываете сон, у него не будет времени на обработку этого буфера. –

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 к гнезду не завершена, и возвращает успех булево, и т.д.

+0

Я не уверен, понимаю ли я ваше решение. Можете ли вы написать некоторый (псевдо) код, чтобы я мог понять, что вы имеете в виду? – 585connor

Смежные вопросы