Я использую Ratchet PHP для отправки сообщений клиентам, и я использую
$server->loop->addPeriodicTimer(1, function () use ($row, $server) {...
Чтобы отправить сообщение каждую секунду. Я могу echo
сообщение и запрос MySQL работают, но я не могу получить доступ к clients
объект в $server
Я могу добраться до $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
что я, вероятно, не должен был, но это решило мою проблему.
Я мог получить доступ к clients
пункт, делая $server->app->_httpServer->component->clients
,
Благодаря Felippe Duarte
для выделения этого атрибута, я не думал об этом.