add
int \Workerman\Timer::add(float $time_interval, callable $callback [,$args = array(), bool $persistent = true])
특정 함수 또는 클래스 메소드를 정기적으로 실행합니다.
주의: 타이머는 현재 프로세스 내에서 실행되며, Workerman 내에서 타이머를 실행하기 위해 새로운 프로세스나 스레드를 생성하지 않습니다.
매개변수
time_interval
얼마나 자주 실행되는지, 단위는 초이며, 소수를 지원하여 0.001까지도 가능하므로 밀리초 수준의 정밀도를 제공합니다.
callback
콜백 함수주의: 콜백 함수가 클래스의 메소드인 경우, 메소드는 public 속성이어야 합니다
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::runAll();
2. 특정 프로세스에서만 타이머 설정
하나의 워커 인스턴스에 4개의 프로세스가 있으며, id 번호가 0인 프로세스에서만 타이머를 설정합니다.
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
$worker->count = 4;
$worker->onWorkerStart = function(Worker $worker)
{
// id 번호 0인 프로세스에서만 타이머를 설정하고, 다른 1, 2, 3번 프로세스는 타이머를 설정하지 않습니다.
if($worker->id === 0)
{
Timer::add(1, function(){
echo "4개의 워커 프로세스 중 0번 프로세스에서만 타이머 설정\n";
});
}
};
// 워커 실행
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();
// connection 객체에 임시로 timer_id 속성을 추가하여 타이머 id를 저장
$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::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();
// connection 객체에 임시로 timer_id 속성을 추가하여 타이머 id를 저장
$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::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::runAll();
6. 타이머 함수가 클래스의 메소드인 경우
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// 주의, 콜백 함수 속성은 반드시 public이어야 합니다.
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::runAll();
7. 타이머 함수가 클래스의 메소드(클래스 내부에서 타이머 사용)
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// 주의, 콜백 함수 속성은 반드시 public이어야 합니다.
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::runAll();
8. 타이머 함수가 클래스의 정적 메소드인 경우
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// 주의, 정적 메소드이며, 콜백 함수 속성도 반드시 public이어야 합니다.
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::runAll();
9. 타이머 함수가 클래스의 정적 메소드(네임스페이스 포함)
namespace Task;
use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
class Mail
{
// 주의, 정적 메소드이며, 콜백 함수 속성도 반드시 public이어야 합니다.
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::runAll();
10. 타이머 내에서 현재 타이머 삭제 (use 클로저 방식으로 $timer_id 전달)
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_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::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_id = Timer::add(1, array($mail, 'send'), array('to', 'content', &$timer_id));
};
// 워커 실행
Worker::runAll();