Search code examples
phpratchetreactphp

Publish to subscribed clients at scheduled times using reachphp or ratchet


I'm new to reactphp. I dabbled in node.js. I'm researching a project that requires events to fire at specific times and get published to the subscribed clients. Is this something that the EventLoop would be suited for? Any direction for how I could approach this?


Solution

  • Your assumption of using the React EventLoop is correct. You can use a periodic timer to trigger sending messages. Since you mentioned Ratchet and published+subscribe I'm going to assume you're doing this using WAMP over WebSockets. Here's some sample code:

    <?php
    use Ratchet\ConnectionInterface;
    
    class MyApp implements \Ratchet\Wamp\WampServerInterface {
        protected $subscribedTopics = array();
    
        public function onSubscribe(ConnectionInterface $conn, $topic) {
            // When a visitor subscribes to a topic link the Topic object in a  lookup array
            if (!array_key_exists($topic->getId(), $this->subscribedTopics)) {
                $this->subscribedTopics[$topic->getId()] = $topic;
            }
        }
        public function onUnSubscribe(ConnectionInterface $conn, $topic) {}
        public function onOpen(ConnectionInterface $conn) {}
        public function onClose(ConnectionInterface $conn) {}
        public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {}
        public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {}
        public function onError(ConnectionInterface $conn, \Exception $e) {}
    
        public function doMyBroadcast($topic, $msg) {
            if (array_key_exists($topic, $this->subscribedTopics)) {
                $this->subscribedTopics[$topic]->broadcast($msg);
            }
        }
    }
    
        $myApp = new MyApp;
        $loop = \React\EventLoop\Factory::create();
        $app = new \Ratchet\App('localhost', 8080, '127.0.0.1', $loop);
        $app->route('/my-endpoint', $myApp);
    
        // Every 5 seconds send "Hello subscribers!" to everyone subscribed to the "theTopicToSendTo" topic/channel
        $loop->addPeriodicTimer(5, function($timer) use ($myApp) {
            $myApp->doMyBroadcast('theTopicToSendTo', 'Hello subscribers!');
        });
    
        $app->run();