Need timer function inside Chat class [SOLVED]
I have been studying how to do this but I have not found a working example. I am using the Chat script to receive messages from a variable number of clients. The messages are synchronized to arrived at about the same time. A timer shall be set or its value recorded on the first message. If after 3 seconds there are no more messages, received messages will be concatenated into one message and sent to a destination client. I think I would like to use either addPeriodicTimer() or addTimer().
For example I found this but it seems out of date. https://github.com/ratchetphp/Ratchet/issues/171 $loop is already defined so I get:
PHP Fatal error: Uncaught TypeError: Argument 1 passed to MyApp\Chat::__construct() must be an instance of MyApp\React\EventLoop\LoopInterface, instance of React\EventLoop\StreamSelectLoop given, called in /usr/bin/chat-server.php on line 9 and defined in /usr/src/MyApp/Chat.php:40
you are probably using the wrong $loop since it's not an instance of the required interface.
Also, for your usecase addTimer() is probably the right choice.
MyApp\React\EventLoop\LoopInterface should be React\EventLoop\LoopInterface.
I removed the MyApp namespace, moved everything to the base directory, and got around the problem above identified by WyriHaximus. But now when I try to follow the idea given in the #171 above, I have a new problem.
PHP Recoverable fatal error: Object of class React\EventLoop\StreamSelectLoop could not be converted to string in /root/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php on line 59
Here is line 59 of IoServer.php. I think my code attempting to insert a timer is interfering with the variable $loop.
$socket = new Reactor($address . ':' . $port, $loop);
Here is chat-server.php. I have added $loop variable as per example #171
`use Ratchet\Server\IoServer;
//use MyApp\Chat;
require 'Chat.php';
require 'vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$server = IoServer::factory(
new Chat($loop),
47870,
$loop
);
$server->run();`
Here are the relevant lines of Chat.php. I added timer code inside __construct()
`//namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
require 'vendor/autoload.php';
class Chat implements MessageComponentInterface {
public function __construct(React\EventLoop\LoopInterface $loop) {
$loop->addPeriodicTimer(1, function () {
echo "Tick\n";
});
$this->clients = new \SplObjectStorage;
}`
I solved this by using the example code on https://prodevsblog.com/questions/158171/how-do-i-use-a-ratchet-server-ioserver-object-after-run-executed/
In chat-server,php I replaced $server = IoServer::factory( and now my code is
$loop = React\EventLoop\Factory::create();
$socket = new \React\Socket\Server('[address:port]', $loop);
$server = new \Ratchet\Server\IoServer(
new Chat($loop),
$socket,
$loop
);
$server->run();
In Chat.php __construct is this, where keepTime is my callback function.
public function __construct(React\EventLoop\LoopInterface $loop) {
$loop->addPeriodicTimer(1, function (\React\EventLoop\Timer\Timer $timer) {
$this->keepTime();
});
$this->clients = new \SplObjectStorage;
}
If anything could be done better, please comment.