PHP вызывает функцию экземпляра из потока - PullRequest
0 голосов
/ 08 апреля 2019

Я использую поток для запуска асинхронной задачи, пока мой сервер веб-сокетов обрабатывает соединение. Поток имеет сокет соединения с другим открытым сервером.

Когда клиент подключается к веб-сокету, сокет вызывает функцию в этом классе, которая отправляет сообщение всем подключенным клиентам. Когда поток получает сообщение, он вызывает ту же функцию.

Моя проблема в том, что websocket не отправляет сообщение всем подключенным клиентам, когда поток вызывает эту функцию. Переменная, в которую сохраняются все клиенты, отличается при обоих вызовах функций, хотя я вызываю функцию в экземпляре класса.

Я уже пытался добавить переменную клиентов в качестве параметра к функции, используя для нее методы получения и установки и сделать ее общедоступной. Все пришло к тому же результату.

<?php
set_time_limit(0);

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
require_once 'vendor/autoload.php';

class WorkerThread extends Thread {
    private $connection;
    public $msgHistory;

    public function __construct($connection) {
        $this->connection = $connection;
        $this->msgHistory = array();
    }

    public function run() {
        while (true) {
            // Socket reader would be here

            $msg = "test";

            // Add to message history
            $this->msgHistory[count($this->msgHistory)] = $msg;

            // Send message to all clients
            $this->connection->sendMessageToAllClients(array($msg), false); // Function displays "Connection count: 0"
            }
        }
    }
}

class WebSocketRemoteConsoleHandler implements MessageComponentInterface {
    protected $clients;
    private $worker;

    public function __construct() {
        $this->clients = new \SplObjectStorage;

        $this->worker = new WorkerThread($this);
        $this->worker->start();
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        $this->sendMessageToAllClients($this->worker->msgHistory, true); // Function displays "Connection count: 1"
    }

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }

    public function sendMessageToAllClients($data, $sendMsgHistory) {
        echo "Connection count: " . count($this->clients) . PHP_EOL;
        foreach($this->clients as $client) {
            $client->send(json_encode(array(
                "Messages" => $data,
                "IsComplete" => $sendMsgHistory
            )));
        }
    }
}

$server = IoServer::factory(
    new HttpServer(new WsServer(new WebSocketRemoteConsoleHandler())),
    8080
);
$server->run();
?>

Когда я вызываю метод sendMessageToAllClients() из класса, он показывает Connection count: 1. Когда я вызываю функцию из потока в том же экземпляре класса websocket, он показывает Connection count: 0.

Я ожидаю, что оба вызова функций должны показать, что 1 клиент подключен (Connection count: 1).

(я уже запустил webocket и подключился к нему с помощью javascript)

...