dongwen3410 2018-07-16 16:47
浏览 69
已采纳

RatchetPHP无法向循环中的所有客户端发送消息

I'm using Ratchet PHP to send messages to clients, and I'm using

$server->loop->addPeriodicTimer(1, function () use ($row, $server) {...

To send a message every second. I can echo the message and the MySQL query works, but I am unable to actually access the clients object in $server, I can get to $server->app, but then when I do ->clients after that, it tells me that $clients doesn't exist.

To clarify, this isn't a problem when I don't use new HttpServer(...) but, without it, the browser console says the websocket handshake isn't valid, so that isn't a good workaround.

I've used print_r($server) and have confirmed that the clients object is inside a _httpServer:protected item. If I can access this, I'd be able to send messages, I think.

The code for the actual server video-server.php:

<?php
include "../../include/db.info.php";

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use React\EventLoop\Factory;
use MyApp\Chat;

require dirname(__DIR__) . '/vendor/autoload.php';

$server = IoServer::factory(
                new HttpServer(
                new WsServer(
                new Chat()
                )
                ), 888
);

$pdo = new PDO("mysql:host=localhost;port=3306;dbname=erewhon", "root", "");

$getUsername = $pdo->prepare("SELECT * FROM messages WHERE id=201");
$getUsername->execute();

$row = $getUsername->fetch(PDO::FETCH_ASSOC);

$server->loop->addPeriodicTimer(1, function () use ($row, $server) {        
    /*foreach ($server->app->component->clients as $client) {                  
            $client->send("hello client");          
    }*/
    print_r($server->app);
});

$server->run();
?>

The code for the classes file, chat.php:

<?php
namespace MyApp;
header("Content-Type: application/json; charset=UTF-8");


//include "../../db.info.php";


use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {


    public $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
        echo "Congratulations! the server is now running
";
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})
";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        //dont need this
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected
";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}
";

        $conn->close();
    }

}
?>
  • 写回答

2条回答 默认 最新

  • dongyu1979 2018-07-16 17:47
    关注

    It seems that you can't get that data the way you want. The HttpServer define a protected variable.

    protected $_httpServer; //<--- protected, you can't read from outside.
    public function __construct(HttpServerInterface $component) {
        $this->_httpServer = $component;
        $this->_reqParser  = new HttpRequestParser;
    }
    

    But, you can pass a instance of Chat and keep track of it. It will point to the same memory address.

    Make a try:

    $chat = new Chat(); //<--- ADD THIS LINE
    $server = IoServer::factory(
                new HttpServer(
                  new WsServer(
                    $chat //<----- USE HERE
                  )
                ), 888
              );
    
    ....
    
    $server->loop->addPeriodicTimer(1, function () use ($row, $server, $chat) {        
        /*foreach ($server->app->component->clients as $client) {                  
            $client->send("hello client");          
        }*/
        print_r($server->app);
        print_r($chat->clients); // <---- PRINT HERE TO GET THE INFO
    });
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改