Yoram Kornatzky
2 min readSep 8, 2020

--

Photo by nile on Pixabay

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

Entrepreneur, Auctibles: https://auctibles.com, 25 years of development experience, Ph.D. Computer Science, https://yoramkornatzky.com