RatchetPHP 无法向循环中的所有客户端发送消息
RatchetPHP unable to send messages to all clients in loop
我正在使用 Ratchet PHP 向客户端发送消息,我正在使用
$server->loop->addPeriodicTimer(1, function () use ($row, $server) {...
每秒发送一条消息。我可以 echo
消息和 MySQL 查询有效,但我无法实际访问 $server
中的 clients
对象,我可以访问 $server->app
,但是当我在那之后做 ->clients
时,它告诉我 $clients
不存在。
澄清一下,当我不使用 new HttpServer(...)
时这不是问题,但是如果没有它,浏览器控制台会显示 websocket 握手无效,因此这不是一个好的解决方法.
我使用了 print_r($server)
并确认 clients
对象在 _httpServer:protected
项目中。如果我可以访问它,我想我就可以发送消息了。
实际服务器代码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();
?>
类 文件的代码,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\n";
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
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\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
?>
您似乎无法以您想要的方式获取该数据。
HttpServer 定义了一个受保护的变量。
protected $_httpServer; //<--- protected, you can't read from outside.
public function __construct(HttpServerInterface $component) {
$this->_httpServer = $component;
$this->_reqParser = new HttpRequestParser;
}
但是,您可以传递 Chat
的实例并跟踪它。它将指向相同的内存地址。
试一试:
$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
});
为了以防万一,我在下面找到了我的原始答案,但我想强调一下,接受的答案是正确的方法,只是不要忘记将它传递给 use
我知道我可能不应该这样做来解决我的问题,但它解决了它,所以这就足够了:
我去了 vendor\cboden\ratchet\src\Ratchet\Http
并编辑了 HttpServer.php,特别是变量 protected $_httpServer
,并将其更改为 public $_httpServer
,我可能不应该这样做,但是解决了我的问题。
我可以通过 $server->app->_httpServer->component->clients
.
访问 clients
项
感谢 Felippe Duarte
突出显示此属性,我没想到。
我正在使用 Ratchet PHP 向客户端发送消息,我正在使用
$server->loop->addPeriodicTimer(1, function () use ($row, $server) {...
每秒发送一条消息。我可以 echo
消息和 MySQL 查询有效,但我无法实际访问 $server
中的 clients
对象,我可以访问 $server->app
,但是当我在那之后做 ->clients
时,它告诉我 $clients
不存在。
澄清一下,当我不使用 new HttpServer(...)
时这不是问题,但是如果没有它,浏览器控制台会显示 websocket 握手无效,因此这不是一个好的解决方法.
我使用了 print_r($server)
并确认 clients
对象在 _httpServer:protected
项目中。如果我可以访问它,我想我就可以发送消息了。
实际服务器代码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();
?>
类 文件的代码,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\n";
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
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\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
?>
您似乎无法以您想要的方式获取该数据。 HttpServer 定义了一个受保护的变量。
protected $_httpServer; //<--- protected, you can't read from outside.
public function __construct(HttpServerInterface $component) {
$this->_httpServer = $component;
$this->_reqParser = new HttpRequestParser;
}
但是,您可以传递 Chat
的实例并跟踪它。它将指向相同的内存地址。
试一试:
$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
});
为了以防万一,我在下面找到了我的原始答案,但我想强调一下,接受的答案是正确的方法,只是不要忘记将它传递给 use
我知道我可能不应该这样做来解决我的问题,但它解决了它,所以这就足够了:
我去了 vendor\cboden\ratchet\src\Ratchet\Http
并编辑了 HttpServer.php,特别是变量 protected $_httpServer
,并将其更改为 public $_httpServer
,我可能不应该这样做,但是解决了我的问题。
我可以通过 $server->app->_httpServer->component->clients
.
clients
项
感谢 Felippe Duarte
突出显示此属性,我没想到。