December 04, 2019

How to Do Requests Polling in ReactPHP Connector

ReactPHP is an interesting project. Recently when I got a project interfacing with UHF RFID reader through a Soyal Controller, I thought I would give it a try. The documentation was mostly self-sufficient and easy to follow, so it was easy to get setup to start making my first request and receive my first response. All good.

Now how do I do polling? A quick search revealed the addPeriodicTimer() function, perfect for what I need. But I also very quickly ran into some problems as the examples are mostly about echo-ing items. Just how do I loop my polling requests with addPeriodicTimer()?

Well I figured it out.


Basic Project Layout

Say we have a very basic project as such:

<?php
require __DIR__ . '/vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$connector = new React\Socket\Connector($loop);
$bytes = 'ff005aa500040118e6ff';

$connector->connect('192.168.0.100:9090')->then(function (React\Socket\ConnectionInterface $connection) use ($loop, $bytes) {
	echo '[STARTED]' . PHP_EOL;

	echo '[SEND]: '. $bytes . PHP_EOL;
	$connection->write(hex2bin($bytes));

    $connection->on('data', function ($data) {
    	echo '[RECEIVED]: ' . $data . PHP_EOL;
	});

	$connection->on('close', function () {
        echo '[CLOSED]' . PHP_EOL;
    });
});

$loop->run();

Basically the project initiates a socket connection that would send a $bytes string to a target 192.168.0.100:9090 via TCP/IP, then listens for the response from the target. In my case this is a Soyal Controller, in your case this could be just another server.


Polling the Requests

Now to add polling, simply wrap the write() function under addPeriodicTimer()! Then we also add a cancelTimer() under the close() function so that when the connection is closed we would stop the timer.

There is no need to modify anything else, the new data received will automatically be picked up and displayed.

<?php
require __DIR__ . '/vendor/autoload.php';

$loop = React\EventLoop\Factory::create();
$connector = new React\Socket\Connector($loop);
$bytes = 'ff005aa500040118e6ff';

$connector->connect('192.168.0.100:9090')->then(function (React\Socket\ConnectionInterface $connection) use ($loop, $bytes) {
	echo '[STARTED]' . PHP_EOL;

	// Add the codes here
	$timer = $loop->addPeriodicTimer(1, function() use ($connection, $bytes) {
		echo '[SEND]: '. $bytes . PHP_EOL;
		$connection->write(hex2bin($bytes));
    });
    // Add the codes here

    $connection->on('close', function () use ($timer, $loop) {
    	// Add the codes here [2]
        $loop->cancelTimer($timer);
        // Add the codes here [2]
        echo '[CLOSED]' . PHP_EOL;
    });

	$connection->on('close', function () {
        echo '[CLOSED]' . PHP_EOL;
    });
});

$loop->run();

Try it out yourself!

***