add
int \Workerman\Timer::add(float $time_interval, callable $callback [,$args = array(), bool $persistent = true])
Планировщик для выполнения определенной функции или метода класса.
Примечание: таймеры выполняются в текущем процессе, в Workerman не создаются новые процессы или потоки для выполнения таймеров.
Параметры
time_interval
Интервал времени, через который выполняется задача, в секундах, поддерживает десятичные дроби, может быть задан с точностью до 0.001, то есть до миллисекунд.
callback
Функция обратного вызова Примечание: если функция обратного вызова является методом класса, этот метод должен быть публичным
args
Параметры функции обратного вызова, должны быть в виде массива, элементы массива — это значения параметров
persistent
Является ли таймер постоянным, если вы хотите выполнить задачу только один раз, передайте false (задачи, выполняемые один раз, будут автоматически уничтожены после выполнения, не нужно вызывать Timer::del()), по умолчанию true, то есть выполняется постоянно.
Возвращаемое значение
Возвращает целое число, представляющее идентификатор таймера timerid, этот таймер можно уничтожить, вызвав Timer::del($timerid).
Примеры
1. Таймер с анонимной функцией (замыкание)
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
// Количество процессов для выполнения задач с таймерами, учитывайте возможные проблемы с конкурентностью
$task->count = 1;
$task->onWorkerStart = function(Worker $task)
{
// Выполнять каждые 2.5 секунды
$time_interval = 2.5;
Timer::add($time_interval, function()
{
echo "задача запущена\n";
});
};
// Запускаем worker
Worker::runAll();
2. Установка таймера только в определенном процессе
У экземпляра worker есть 4 процесса, таймер устанавливается только в процессе с идентификатором 0.
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
$worker->count = 4;
$worker->onWorkerStart = function(Worker $worker)
{
// Устанавливаем таймер только в процессе с идентификатором 0, остальные процессы 1, 2, 3 не устанавливают таймер
if($worker->id === 0)
{
Timer::add(1, function(){
echo "4 процесса worker, таймер установлен только в процессе 0\n";
});
}
};
// Запускаем worker
Worker::runAll();
3. Таймер с анонимной функцией, передача параметров через замыкание
use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Установка таймера для соответствующего соединения при установлении подключения
$ws_worker->onConnect = function(TcpConnection $connection)
{
// Выполнять каждые 10 секунд
$time_interval = 10;
$connect_time = time();
// Временно добавляем свойство timer_id объекту connection для хранения идентификатора таймера
$connection->timer_id = Timer::add($time_interval, function()use($connection, $connect_time)
{
$connection->send($connect_time);
});
};
// Удаление таймера для соответствующего соединения при его закрытии
$ws_worker->onClose = function(TcpConnection $connection)
{
// Удаляем таймер
Timer::del($connection->timer_id);
};
// Запускаем worker
Worker::runAll();
4. Таймер с анонимной функцией, передача параметров через интерфейс таймера
use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Установка таймера для соответствующего соединения при установлении подключения
$ws_worker->onConnect = function(TcpConnection $connection)
{
// Выполнять каждые 10 секунд
$time_interval = 10;
$connect_time = time();
// Временно добавляем свойство timer_id объекту connection для хранения идентификатора таймера
$connection->timer_id = Timer::add($time_interval, function($connection, $connect_time)
{
$connection->send($connect_time);
}, array($connection, $connect_time));
};
// Удаление таймера для соответствующего соединения при его закрытии
$ws_worker->onClose = function(TcpConnection $connection)
{
// Удаляем таймер
Timer::del($connection->timer_id);
};
// Запускаем worker
Worker::runAll();
5. Таймер с обычной функцией
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
// Обычная функция
function send_mail($to, $content)
{
echo "отправка письма...\n";
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
$to = 'workerman@workerman.net';
$content = 'hello workerman';
// Выполнять задачу по отправке письма через 10 секунд, последний параметр false, означает выполнить только один раз
Timer::add(10, 'send_mail', array($to, $content), false);
};
// Запускаем worker
Worker::runAll();
6. Таймер с методом класса
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// Примечание: свойства функции обратного вызова должны быть публичными
public function send($to, $content)
{
echo "отправка письма...\n";
}
}
$task = new Worker();
$task->onWorkerStart = function($task)
{
// Отправка письма через 10 секунд
$mail = new Mail();
$to = 'workerman@workerman.net';
$content = 'hello workerman';
Timer::add(10, array($mail, 'send'), array($to, $content), false);
};
// Запускаем worker
Worker::runAll();
7. Таймер с методом класса (использование таймера внутри класса)
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// Примечание: свойства функции обратного вызова должны быть публичными
public function send($to, $content)
{
echo "отправка письма...\n";
}
public function sendLater($to, $content)
{
// Поскольку метод колбэка принадлежит текущему классу, первый элемент массива обратного вызова будет $this
Timer::add(10, array($this, 'send'), array($to, $content), false);
}
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
// Отправка письма через 10 секунд
$mail = new Mail();
$to = 'workerman@workerman.net';
$content = 'hello workerman';
$mail->sendLater($to, $content);
};
// Запускаем worker
Worker::runAll();
8. Таймер с статическим методом класса
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// Примечание: это статический метод, свойства функции обратного вызова также должны быть публичными
public static function send($to, $content)
{
echo "отправка письма...\n";
}
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
// Отправка письма через 10 секунд
$to = 'workerman@workerman.net';
$content = 'hello workerman';
// Регулярный вызов статического метода класса
Timer::add(10, array('Mail', 'send'), array($to, $content), false);
};
// Запускаем worker
Worker::runAll();
9. Таймер с статическим методом класса (с пространством имен)
namespace Task;
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// Примечание: это статический метод, свойства функции обратного вызова также должны быть публичными
public static function send($to, $content)
{
echo "отправка письма...\n";
}
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
// Отправка письма через 10 секунд
$to = 'workerman@workerman.net';
$content = 'hello workerman';
// Регулярный вызов статического метода класса с пространством имен
Timer::add(10, array('\Task\Mail', 'send'), array($to, $content), false);
};
// Запускаем worker
Worker::runAll();
10. Уничтожение текущего таймера из таймера (передача $timer_id через use замыкания)
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
// Счетчик
$count = 1;
// Чтобы $timer_id мог быть правильно передан внутрь функции обратного вызова, перед его именем необходимо добавить адресный символ &
$timer_id = Timer::add(1, function()use(&$timer_id, &$count)
{
echo "Таймер работает $count\n";
// После 10 выполнений уничтожить текущий таймер
if($count++ >= 10)
{
echo "Timer::del($timer_id)\n";
Timer::del($timer_id);
}
});
};
// Запускаем worker
Worker::runAll();
11. Уничтожение текущего таймера из таймера (передача $timer_id через параметры)
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
public function send($to, $content, $timer_id)
{
// Временно добавляем свойству текущего объекта count, чтобы отслеживать количество выполнений таймера
$this->count = empty($this->count) ? 1 : $this->count;
// После 10 выполнений уничтожить текущий таймер
echo "отправка письма {$this->count}...\n";
if($this->count++ >= 10)
{
echo "Timer::del($timer_id)\n";
Timer::del($timer_id);
}
}
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
$mail = new Mail();
// Чтобы $timer_id мог быть правильно передан внутрь функции обратного вызова, перед его именем необходимо добавить адресный символ &
$timer_id = Timer::add(1, array($mail, 'send'), array('to', 'content', &$timer_id));
};
// Запускаем worker
Worker::runAll();