2017-03-17 12 views
4

Ich habe eine App mit PHP (auf Websockets) und ich muss ein paar Timer für jeweils drei Sekunden erstellen. Wenn die Zeit in den Timern abgelaufen ist, ändere ich die Bool-Variable. Jeder Timer ändert seine eigene Variable. Ich kann nicht schlafen, weil mein Programm aktiv sein muss.Kann ich den asynchronen Timer in PHP verwenden und wie?

Ich dachte, der Timer in der Reaktion php wäre asynchron, aber es verhält sich genau wie sleep(). Hier ist mein Code:

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

    $loop->run(); 

Wie kann ich einen asynchronen Timer machen?

+0

Warum verwenden Sie keinen Cronjob für jeden Timer? –

+0

@Victor Radu Ich kenne Cron noch nicht. Diese Aufgabe kann mit Cron gelöst werden? – Log

+1

Der 'cron' Service hilft hier nicht. Es wird verwendet, um Befehle auf dem System zu bestimmten Zeitpunkten (mit einer Auflösung von 1 Minute) auszuführen. – axiac

Antwort

1

Sie könnten Hintergrundarbeiter verwenden. Gearman ist großartig für diese Dinge.

+0

danke für den Link, ich versuche es zu verwenden – Log

+0

@Ramy Talal - Ich mag die Idee, aber ich glaube nicht, Gearmman unterstützt verzögerte Arbeitsplätze.Der Hintergrundarbeiter müsste also immer noch für 3 Sekunden schlafen und der PHP-Verbraucher würde daher immer noch ** blockieren **. Also richtige Idee, falsches Werkzeug? – Gravy

+0

@Gravy In gewisser Weise ist es möglich, einen Job zu verzögern: https://medium.com/@abbiya/yo-yo-yo-include-gearman-and-redis-in-your-php-app-1d9a9e0b40ac#.78cloax7m Aber Bohnenkohl wäre in der Tat besser. –

0

Da ich Windows benutze und Gearman schlecht installiert ist, fand ich eine andere Entscheidung in Form von Pthreads. Ich erstelle einfach einen neuen Thread und setze den Schlaf (3).

1

Ich mag die Empfehlung von Ramy Talal, einen Warteschlangenserver wie Gearman zu verwenden, aber ich glaube nicht, dass Gearman verzögerte Aufträge unterstützt - es wird im Gearman-Protokoll weder http://gearman.org/protocol/ erwähnt. Ich würde mit etwas wie Bohnenkohl gehen.

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

Sie haben einen PHP-Prozess verantwortlich für die mit einer Verzögerung in einer Warteschlange einen Job setzen und einen zweiten PHP-Prozess aus der Warteschlange für das Konsumieren.

Eine nette Bibliothek Client für Bohnenstange ist Pheanstalk. https://github.com/pda/pheanstalk, die Sie über Composer installieren können.

einfaches Anwendungsbeispiel:

Produzent

$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. 
); 

Consumer

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

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

So im Wesentlichen, legt der Hersteller einen Job auf die choose_tube_name Rohr/Warteschlange mit einer 3 Sekunden Verzögerung. Nach 3 Sekunden ist es bereit, von jedem Verbraucher konsumiert zu werden, der in der Warteschlange zuhört.

Der Verbraucher sitzt dort warten auf einen Job, wenn man ankommt, es reserviert es, dann echos die Ausgabe und löscht den Job und weil es in einer Weile Schleife ist, wird es warten, bis ein anderer Job kommt zu verarbeiten.

Um zu skalieren, können Sie mehrere Produzenten und mehrere Verbraucher haben. Eine Sache, an die Sie sich jedoch erinnern sollten, ist, dass Ihr Verbraucher im obigen Beispiel ein lang andauernder Prozess ist. Achten Sie also auf Speicherauslastung/-lecks und seien Sie vorsichtig bei der Freigabe von Objekten zwischen Jobs. z.B. Wenn Sie eine Klasse außerhalb der while-Schleife instanziieren und sie in der while-Schleife verwenden/ändern, werden die Eigenschaften in andere Jobs verschoben.

+0

danke, ich überprüfe es – Log

+0

Endlich stoppte ich diese Entscheidung. Ihr Beispiel funktioniert gut. Aber ich verstehe nicht - wie kann ich Variable in Producer-Datei von Consumer-Datei ändern. Darf ich Variable durch Referenz in Put-Methode übergeben? Oder gibt es keine Möglichkeit, die Variable in der Producer-Datei vom Consumer zu ändern? Weißt du irgendetwas darüber? – Log

+0

@Log - Wenn Sie ein PHP-Objekt erstellen und es zu einem Produzenten veröffentlichen möchten, dann lesen und manipulieren Sie das Objekt in einem Consumer, müssen Sie es serialisieren und deserialisieren. Ich benutze 'json_encode' /' json_decode', aber Sie können auch http://php.net/manual/en/function.serialize.php verwenden. – Gravy

Verwandte Themen