Ratchet icon indicating copy to clipboard operation
Ratchet copied to clipboard

Need timer function inside Chat class [SOLVED]

Open nturns opened this issue 5 years ago • 4 comments

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

nturns avatar Oct 07 '20 09:10 nturns

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.

nineff avatar Oct 07 '20 17:10 nineff

MyApp\React\EventLoop\LoopInterface should be React\EventLoop\LoopInterface.

WyriHaximus avatar Oct 07 '20 17:10 WyriHaximus

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;
    }`

nturns avatar Oct 08 '20 15:10 nturns

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.

nturns avatar Oct 09 '20 10:10 nturns