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を渡します(1回だけ実行されるタスクは実行後自動的に破棄され、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 "task run\n";
});
};
// workerを実行
Worker::runAll();
2、特定のプロセスのみでタイマーを設定
1つのworkerインスタンスに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つの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();
// 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を実行
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を実行
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 = 'こんにちは workerman';
// 10秒後にメール送信タスクを実行、最後の引数にfalseを渡し、1回のみ実行
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でなければなりません
public function send($to, $content)
{
echo "メールを送信中 ...\n";
}
}
$task = new Worker();
$task->onWorkerStart = function($task)
{
// 10秒後にメールを1回送信
$mail = new Mail();
$to = 'workerman@workerman.net';
$content = 'こんにちは 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でなければなりません
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秒後にメールを1回送信
$mail = new Mail();
$to = 'workerman@workerman.net';
$content = 'こんにちは workerman';
$mail->sendLater($to, $content);
};
// workerを実行
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秒後にメールを1回送信
$to = 'workerman@workerman.net';
$content = 'こんにちは 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でなければなりません
public static function send($to, $content)
{
echo "メールを送信中 ...\n";
}
}
$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
// 10秒後にメールを1回送信
$to = 'workerman@workerman.net';
$content = 'こんにちは 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_id = Timer::add(1, function()use(&$timer_id, &$count)
{
echo "Timer run $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_id = Timer::add(1, array($mail, 'send'), array('to', 'content', &$timer_id));
};
// workerを実行
Worker::runAll();