Может ли цикл Ratchet/ReactPHP прослушивать более одного порта?

Я настроил ReactPHP в качестве прослушивателя WebSocket, чтобы я мог отправлять обновления почти в реальном времени в подписанные браузеры. Это выглядит так:

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Listener;

$rootPath = realpath(__DIR__ . '/..');
require_once $rootPath . '/vendor/autoload.php';

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Listener()
        )
    ),
    8081
);
$server->run();

Все эти классы, кроме Listener, являются частью Ratchet, а Listener является моей реализацией обработчика \Ratchet\MessageComponentInterface, который отвечает на события открытия/закрытия/ошибки подключения WebSockets.

Я хотел бы, чтобы этот скрипт был доступен для системы очередей, которую я создаю, и, поскольку это системный канал, я хотел бы выставить его на другом порту, чтобы он был недоступен из Интернета. В идеале это должно быть на HTTP, а не на WebSocket; Я успешно использовал клиент PHP WebSocket для связи с этим слушателем, но это немного сложно по сравнению с вызовом file_get_contents('http://...')!

Можно предположить, что внутренний цикл React (например, StreamSelectLoop::streamSelect) блокируется только на короткое время (см. здесь), поэтому чувствуется возможность внутреннего управления несколькими отдельными потоками. В идеале я хотел бы, чтобы дополнительный порт обрабатывался отдельным прослушивателем для изоляции безопасности (на случай, если уязвимость в Guzzle позволяет злоумышленнику выглядеть как исходящий из ограниченного порта, когда на самом деле он пришел из Интернета порт).

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


Одним из решений этой проблемы является добавление белого списка IP-адресов в прослушиватель WebSocket для определенных типов сообщений. Я могу сделать это в краткосрочной перспективе, но прослушивание через другой порт было бы гораздо более приятным решением.


person halfer    schedule 28.07.2017    source источник


Ответы (1)


Я нашел один способ, это может быть не лучшая практика, но вы можете вручную добавить сокет, например:

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Listener;
use React\Socket\Server as Reactor;

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Listener()
        )
    ),
    8081 //Port 1
);
$socket = new Reactor($server->loop);
$socket->listen(8082, '0.0.0.0'); //Port 2
$socket->on('connection', [$server, 'handleConnect']);
$server->run();
person Grey    schedule 28.07.2017
comment
Да, это отличное начало, спасибо. Я не смог найти класс с именем Reactor, но, похоже, он используется в исходном коде Ratchet как псевдоним для React\Socket\Server, поэтому я добавил его как use, и сервер запустился. Теперь он прослушивает оба порта и направляет их одному и тому же обработчику. Это помогло мне лучше, так как теперь я могу прочитать информацию о порте в Listener для фильтрации безопасности. - person halfer; 28.07.2017
comment
Однако мне бы очень хотелось иметь возможность добавить второй порт и совершенно отдельный обработчик, чтобы было некоторое разделение между двумя портами. Я хотел бы настроить второй сервер как обычный HTTP, а не WebSocket. Вы считаете, что это возможно? Я еще не совсем разобрался с ReactPHP. - person halfer; 28.07.2017