2017-03-17 23 views
4

私はPHP(ウェブソケット上)でアプリを持っており、それぞれ3秒間続くいくつかのタイマーを作成する必要があります。時間がタイマーになると、私はブール変数を変更します。各タイマーはそれ自身の変数を変更します。私のプログラムはアクティブでなければならないので、私は睡眠を使うことができません。PHPで非同期タイマーを使用する方法は?

私は反応するPHPのタイマーは非同期だと思ったが、それはsleep()のように振舞う。ここに私のコード:

$loop = \React\EventLoop\Factory::create(); 
    $timer = $loop->addTimer(3, function() { 
     // some acts 
    }); 

    $loop->run(); 

私は非同期タイマーを作ることができますか?

+0

なぜタイマーごとにcronjobを使用しないのですか? –

+0

@Victor Radu私はまだcronを知らない。この作業はcronを使用して解決できますか? – Log

+1

'cron'サービスはここでは役に立ちません。これは、システムのある時点(1分の解像度)でコマンドを実行するために使用されます。 – axiac

答えて

1

バックグラウンドワーカーを使用できます。 Gearmanはこれらのことに最適です。

+0

リンクのためにありがとう、私はそれを使用しようとする – Log

+0

@ラミータラル - 私は考えが好きですが、私はギアマンが遅れた仕事をサポートするとは思わない。したがって、バックグラウンドワーカーはまだ3秒間スリープ状態を維持する必要があるため、PHPコンシューマーはまだ**ブロックされます**。そのような正しいアイデア、間違ったツールですか? – Gravy

+0

@Gravyある意味、ジョブを遅らせることができます:https://medium.com/@abbiya/yo-yo-yo-include-gearman-and-redis-in-your-php-app-1d9a9e0b40ac#.78cloax7mしかし、Beanstalkdは本当に良いでしょう。 –

0

私はウィンドウを使用しているので、Gearmanがひどくインストールされているため、pthreadsという形で別の決定が見つかりました。私は単に新しいスレッドを作成し、sleep(3)を入れます。

1

ギアマンのようなキューイングサーバーを使用することを推奨しますが、ギアマンが遅れたジョブをサポートしているとは思われません。ギアマンプロトコルのいずれの言及もありません。http://gearman.org/protocol/私はBeanstalkdのようなものに行くだろう。

http://kr.github.io/beanstalkd/

あなたは1つの遅延でキューに仕事を置くための責任PHPプロセス、およびキューから消費するための第二のPHPのプロセスを持っています。

beanstalkの素晴らしいライブラリクライアントはpheanstalkです。 https://github.com/pda/pheanstalkを作ってください。

簡単な使用例:

プロデューサー

$pheanstalk = new Pheanstalk('127.0.0.1'); 

$delay = 3; // delay in seconds 
$pheanstalk 
    ->useTube('choose_tube_name') 
    ->put("job payload goes here\n", 
     PheanstalkInterface::DEFAULT_PRIORITY, // 1024 as standard 
     $delay, 
     PheanstalkInterface::DEFAULT_TTR // I think that after 60 seconds by default, if not deleted by consumer after reserving job, it is automatically released back onto the queue to be consumed by another consumer. 
); 

消費者

while (1) { 
    $job = $pheanstalk 
     ->watch('choose_tube_name') 
     ->ignore('default') 
     ->reserve(); 

    echo $job->getData(); 
    $pheanstalk->delete($job); 
} 

だから、本質的に、プロデューサーは3second遅れでchoose_tube_nameチューブ/キューに仕事を置きます。 3秒後に、キューで待機しているすべての消費者が消費する準備が整います。

コンシューマーは、到着すると待っています。消費者はそれを予約し、出力をエコーし​​てジョブを削除します。また、whileループで処理されるため、別のジョブが処理されるまで待機します。

拡大するためには、複数の生産と複数消費者を持つことができます。ただし、上記の例の消費者は長期的なプロセスであることを覚えておく必要があります。したがって、メモリ使用量/リークを監視し、ジョブ間でオブジェクトを共有する点で注意してください。例えばあなたがwhileループの外でクラスをインスタンス化し、それをwhileループの内部で使用/変更すると、そのプロパティは他のジョブに入り込みます。

+0

ありがとう、私はそれをチェックします – Log

+0

最後に私はこの決定をやめました。あなたの例はうまくいきます。しかし、私は理解していません - どのように私は消費者ファイルからプロデューサーファイルの変数を変更することができます。 putメソッドで変数を渡すことができますか?あるいは、プロデューサファイルの変数をコンシューマから変更する方法はありませんか?あなたはそれについて何か知っていますか? – Log

+0

@Log - PHPオブジェクトを作成してプロデューサに公開し、消費者のオブジェクトを読み込んで操作する場合は、シリアル化してデシリアライズする必要があります。 'json_encode' /' json_decode'を使用しますが、http://php.net/manual/en/function.serialize.php – Gravy

関連する問題