&reftitle.examples;
Простые таймеры
stop();
// Остановливаем наблюдателя, если следующий вызов приведёт к десятой (или больше) итерации
Ev::iteration() >= 10 and $w->stop();
});
// Создаём остановленный таймер. Он будет неактивен, пока мы его не запустим
$w_stopped = EvTimer::createStopped(10, 5, function($w) {
echo "Callback-функция таймера, созданного остановленным\n";
// Останавливаем наблюдателя через 2 итерации
Ev::iteration() >= 2 and $w->stop();
});
// Запускаем событийный цикл, пока работает хотя бы один наблюдатель или пока не вызван Ev::stop()
Ev::run();
// Запускаем и смотрим, как он работает
$w_stopped->start();
echo "Запускаем одну итерацию\n";
Ev::run(Ev::RUN_ONCE);
echo "Перезапускаем второго наблюдателя и пытаемся отловить те же события, но не блокируем\n";
$w2->again();
Ev::run(Ev::RUN_NOWAIT);
$w = new EvTimer(10, 0, function() {});
echo "Запускаем блокирующий цикл\n";
Ev::run();
echo "END\n";
?>
]]>
&example.outputs.similar;
Периодический таймер. Срабатывает раз в 10.5 секунд
]]>
Периодический таймер. Использование callback-функции для перезадания интервала
]]>
Периодический таймер. Срабатывает каждые 10.5 секунд, начиная с текущего момента
]]>
Ждём, пока STDIN не станет читаемым
]]>
Используем асинхронный ввод/вывод для доступа к сокету
stop();
// Останавливаем наблюдателя $write_watcher
$w->stop();
$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: google.co.uk\r\n";
$in .= "Connection: Close\r\n\r\n";
if (!socket_write($socket, $in, strlen($in))) {
trigger_error("Ошибка записи $in в сокет", E_USER_ERROR);
}
$read_watcher = new EvIo($socket, Ev::READ, function ($w, $re)
use ($socket, $e_nonblocking)
{
// Сокет доступен для чтения. Читаем 20 байт в неблокирующем режиме
$ret = socket_recv($socket, $out, 20, MSG_DONTWAIT);
if ($ret) {
echo $out;
} elseif ($ret === 0) {
// Все прочтено
$w->stop();
socket_close($socket);
return;
}
// Ловим EINPROGRESS, EAGAIN или EWOULDBLOCK
if (in_array(socket_last_error(), $e_nonblocking)) {
return;
}
$w->stop();
socket_close($socket);
});
Ev::run();
});
$result = socket_connect($socket, $address, $service_port);
Ev::run();
?>
]]>
&example.outputs.similar;
Встраиваем один цикл в другой
]]>
Встраивание цикла, созданного с помощью kqueue в цикл по умолчанию
]]>
Перехватываем сигнал SIGTERM
stop();
});
Ev::run();
?>
]]>
Отслеживаем изменение /var/log/messages
attr();
if ($attr['nlink']) {
printf("Текущий размер: %ld\n", $attr['size']);
printf("Текущее значение atime: %ld\n", $attr['atime']);
printf("Текущее значение mtime: %ld\n", $attr['mtime']);
} else {
fprintf(STDERR, "файл `messages` отсутствует!");
$w->stop();
}
});
Ev::run();
?>
]]>
Отслеживаем изменение /var/log/messages. Избегаем пропуска обновлений с помощью задержки в одну секунду
stop();
$stat = $w->data;
// 1 секунду после последнего изменения файла
printf("Текущий размер: %ld\n", $stat->attr()['size']);
});
$stat = new EvStat("/var/log/messages", 0., function () use ($timer) {
// Сбрасываем наблюдателя $timer
$timer->again();
});
$timer->data = $stat;
Ev::run();
?>
]]>
Отслеживаем изменения статуса процесса
stop();
printf("Процесс %d вышел с кодом %d\n", $w->rpid, $w->rstatus);
});
Ev::run();
// Защита от зомби процессов
pcntl_wait($status);
} else {
// Порождённый потомок
exit(2);
}
?>
]]>