使用 ReactPHP 定期向 Ratchet 中的特定客户端发送消息

Periodically send messages to specific clients in Ratchet using ReactPHP

一般信息
使用 Ratchet PHP 在聊天系统上工作。应我的用户的要求,我正在尝试在特定的聊天室中实施 Triviabot。聊天室实际上 "exist"。相反,它会检查数组中列出了哪些客户端 ID,并且只将消息发送给这些客户端。

我们的想法是每隔 x 秒问一个问题。

问题
实现 ReactPHP 周期性计时器不是问题。这按预期工作。问题是一旦启用计时器,它就会阻止任何与 websocket 的连接。除了客户端说无法建立连接外,没有其他错误。

相关代码

<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use React\EventLoop\Factory;

class Chat implements MessageComponentInterface {
    private $msgLoop;

    public function __construct() {
        $this->startTriviaBot();
    }

    private function startTriviaBot(){
        $this->msgLoop = Factory::create();

        $this->msgLoop->addPeriodicTimer(1, function (){

            // This is working as expected confirming the timer works fine
            echo 'test'.PHP_EOL;

            foreach($this->clientIDsPerRoom['trivia'] as $receiverID){
                if(array_key_exists($receiverID, $this->userObjects)){

                    $this->sendMessage('Trivia', 'trivia', 'Bot test message', $receiverID);
                }
            }
        });

        // Commenting this makes the websocket accept connections again
        $this->msgLoop->run();
    }
}

我所做的研究没有帮助

- 这个通过创建 websocket 直接向所有客户端发送消息,而不是在 MessageComponentInterface 中。它无法访问特定客户端。

- 这基本上是我正在做的,但它导致了我遇到的问题。

嗨,这里是 ReactPHP 核心团队成员。看起来您正在为 运行 计时器创建一个新循环。这确实会停止您创建的用于启动 Ratchet 的初始事件循环。您还需要将为 Ratchet 创建的事件循环传递给这个 class 并使用那个。只能有一个事件循环。 (如果您没有将事件循环传递给 Ratchet,它将为您创建一个并使用它。将一个传递给 Ratchet 将覆盖该行为。)