API Reference: Timer
Полный справочник по классу Timer для работы с таймерами и отложенным выполнением.
Класс Timer
namespace localzet;
class Timer
Класс для управления таймерами и отложенным выполнением задач.
Статические методы
add()
Добавление таймера.
public static function add(
float $timeInterval,
callable $func,
?array $args = [],
bool $persistent = true
): int
Параметры:
$timeInterval- Интервал выполнения в секундах (float, >= 0)$func- Callback функция для выполнения$args- Массив аргументов для передачи в callback$persistent- Повторяющийся таймер (true) или одноразовый (false)
Возвращает:
ID таймера (int) для последующего удаления.
Примеры:
// Повторяющийся таймер (каждую секунду)
$timerId = Timer::add(1.0, function() {
echo "Tick\n";
});
// Одноразовый таймер (через 5 секунд)
$timerId = Timer::add(5.0, function($message) {
echo $message . "\n";
}, ['Delayed message'], false);
// Таймер с несколькими аргументами
$timerId = Timer::add(2.0, function($name, $age) {
echo "$name is $age years old\n";
}, ['John', 30], false);
del()
Удаление таймера.
public static function del(int $timerId): bool
Параметры:
$timerId- ID таймера для удаления
Возвращает:
true если таймер найден и удален, иначе false.
Пример:
$timerId = Timer::add(10.0, function() {
echo "Это не выполнится\n";
});
// Удаление таймера до его выполнения
Timer::del($timerId);
delAll()
Удаление всех таймеров.
public static function delAll(): void
Описание:
Удаляет все активные таймеры. Полезно при остановке сервера.
Пример:
// Очистка всех таймеров
Timer::delAll();
repeat()
Создание повторяющегося таймера.
public static function repeat(
float $timeInterval,
callable $func,
array $args = []
): int
Параметры:
$timeInterval- Интервал повторения в секундах$func- Callback функция$args- Аргументы для callback
Возвращает:
ID таймера.
Пример:
// Heartbeat каждые 30 секунд
$heartbeatId = Timer::repeat(30.0, function() use ($connection) {
$connection->sendPing();
});
// Остановка heartbeat
Timer::del($heartbeatId);
delay()
Создание одноразового таймера (задержка).
public static function delay(
float $timeInterval,
callable $func,
array $args = []
): int
Параметры:
$timeInterval- Задержка в секундах$func- Callback функция$args- Аргументы для callback
Возвращает:
ID таймера.
Пример:
// Выполнение через 3 секунды
Timer::delay(3.0, function($message) {
echo $message . "\n";
}, ['Delayed execution']);
sleep()
Приостановка выполнения на указанное время (для корутин).
public static function sleep(float $delay): void
Параметры:
$delay- Время приостановки в секундах (>= 0)
Описание:
Асинхронная приостановка выполнения. Не блокирует обработку других запросов.
Примеры:
// В Fiber или корутине
use localzet\Timer;
// Правильно - асинхронная задержка
Timer::sleep(1.0); // Не блокирует процесс
// НЕПРАВИЛЬНО - блокирует весь процесс
sleep(1);
Пример использования:
$server->onMessage = function(TcpConnection $connection, $data) {
// Асинхронная задержка перед ответом
Timer::sleep(0.5);
$connection->send('Delayed response');
};
init()
Инициализация таймера.
public static function init(?EventInterface $event = null): void
Параметры:
$event- EventInterface, цикл событий (опционально)
Описание:
Инициализирует систему таймеров. Вызывается автоматически при запуске сервера.
Пример:
// Ручная инициализация (обычно не требуется)
Timer::init(Server::getEventLoop());
Примеры использования
Пример 1: Таймаут для операции
$server->onMessage = function(TcpConnection $connection, $data) {
// Установка таймаута
$timeoutId = Timer::delay(10.0, function() use ($connection) {
$connection->close('Operation timeout');
});
// Асинхронная операция
performAsyncOperation(function($result) use ($connection, $timeoutId) {
// Отмена таймаута при успешном завершении
Timer::del($timeoutId);
$connection->send($result);
});
};
Пример 2: Heartbeat для соединений
$server->onConnect = function(TcpConnection $connection) {
// Создание heartbeat таймера
$connection->context->heartbeatTimer = Timer::repeat(30.0, function() use ($connection) {
if (!$connection->sendPing()) {
// Не удалось отправить - закрываем соединение
Timer::del($connection->context->heartbeatTimer);
$connection->close();
}
});
};
$server->onClose = function(TcpConnection $connection) {
// Удаление heartbeat при закрытии
if (isset($connection->context->heartbeatTimer)) {
Timer::del($connection->context->heartbeatTimer);
}
};
Пример 3: Периодическая очистка
// Очистка временных данных каждые 5 минут
Timer::repeat(300.0, function() {
$now = time();
// Удаление старых записей
foreach ($temporaryData as $key => $data) {
if ($data['expires'] < $now) {
unset($temporaryData[$key]);
}
}
});
Пример 4: Отложенная отправка
$server->onMessage = function(TcpConnection $connection, $data) {
// Отправка ответа с задержкой
Timer::delay(1.0, function() use ($connection, $data) {
$connection->send('Delayed: ' . $data);
});
};
Пример 5: Ограничение частоты запросов
$requestCounts = [];
$server->onMessage = function(TcpConnection $connection, $data) {
$ip = $connection->getRemoteIp();
$now = time();
// Инициализация счетчика
if (!isset($requestCounts[$ip])) {
$requestCounts[$ip] = ['count' => 0, 'resetTime' => $now + 1];
}
// Сброс счетчика каждую секунду
if ($requestCounts[$ip]['resetTime'] <= $now) {
$requestCounts[$ip] = ['count' => 0, 'resetTime' => $now + 1];
}
// Проверка лимита
if (++$requestCounts[$ip]['count'] > 100) {
$connection->close('Rate limit exceeded');
return;
}
// Обработка запроса
$connection->send('OK');
};
Пример 6: Автоматическое переподключение
function connectWithRetry($address, $maxRetries = 3) {
$retryCount = 0;
$tryConnect = function() use ($address, &$retryCount, $maxRetries, &$tryConnect) {
$connection = new AsyncTcpConnection($address);
$connection->onConnect = function() {
echo "Connected successfully\n";
$retryCount = 0; // Сброс счетчика
};
$connection->onClose = function() use (&$retryCount, $maxRetries, &$tryConnect) {
if (++$retryCount <= $maxRetries) {
echo "Reconnecting in 5 seconds... ($retryCount/$maxRetries)\n";
Timer::delay(5.0, $tryConnect);
} else {
echo "Max retries reached\n";
}
};
$connection->connect();
};
$tryConnect();
}
Лучшие практики
1. Всегда удаляйте таймеры при необходимости
// Плохо - утечка таймера
$server->onConnect = function($conn) {
Timer::repeat(1.0, function() use ($conn) {
// Таймер продолжит работать даже после закрытия соединения
});
};
// Хорошо - удаление таймера
$server->onConnect = function($conn) {
$conn->context->timerId = Timer::repeat(1.0, function() use ($conn) {
// Логика
});
};
$server->onClose = function($conn) {
if (isset($conn->context->timerId)) {
Timer::del($conn->context->timerId);
}
};
2. Используйте Timer::sleep() вместо sleep()
// Плохо - блокирует весь процесс
sleep(1);
// Хорошо - асинхронная задержка
Timer::sleep(1.0);
3. Валидация параметров
// Всегда проверяйте параметры перед использованием
if ($delay < 0) {
throw new InvalidArgumentException('Delay must be >= 0');
}
Timer::delay($delay, $callback);
Ограничения
- Таймеры работают только в контексте Localzet Server
- Минимальный интервал зависит от точности системного таймера (обычно ~1ms)
- Максимальный интервал ограничен типом
floatв PHP

