Technology
Timer Server in ReactPHP
In many applications such as auctions, you need a dynamic collection of timers, such that you can add timers, and cancel timers.
We found ReactPHP superior for this. This sweet and simple server sets a new timer specified by a timeout and a task to be performed on timeout. For example sake, the task is just a string to be printed.
The server has three endpoints:
-
GET /timers
- list the active timers -
POST /add
- add a timer, and returns a timer index for future reference -
POST /cancel
- delete a timer by its index
Assuming you have installed ReactPHP using:
composer install react/event-loop
composer install react/http
Composer install nikic/fast-route
The server is:
require __DIR__ . '/vendor/autoload.php';
use React\Http\Server;
use React\Http\Response;
use React\EventLoop\Factory;
use Psr\Http\Message\ServerRequestInterface;
$counter = 0;
$timers = [];
$loop = Factory::create();
$server = new Server(function (ServerRequestInterface $request) use (&$timers, &$loop, &$counter) {
$path = $request->getUri()->getPath();
$method = $request->getMethod();
if ($path === '/timers' && $method === 'GET') {
return new Response(200, ['Content-Type' => 'text/plain'], implode(PHP_EOL, $tasks));
} else if ($path == '/add' && $method === 'POST') {
var_dump($request->getParsedBody());
$task = $request->getParsedBody()['task'] ?? null;
if ($task) {
$timer = $loop->addPeriodicTimer($time, function() use(&$task) {
echo "task:" . $task . "Timeout \n";
});
$timers[$counter++] = $timer;
return new Response(201, $counter);
}
return new Response(400, ['Content-Type' => 'text/plain'], 'Task field is required');
} else if ($path === '/cancel' && $method === 'POST') {
$index = $request->getParsedBody()['index'] ?? null;
if ($index) {
$loop->cancelTimer($tasks[$index]);
}
return new Response(201);
}
return new Response(404, ['Content-Type' => 'text/plain'], 'Not found');
});
$socket = new \React\Socket\Server('127.0.0.1:8000', $loop);
$server->listen($socket);
echo 'Listening on ' . str_replace('tcp:', 'http:', $socket->getAddress()) . "\n";
$loop->run();
Yoram Kornatzky
Yoram Kornatzky