I've set up ReactPHP as a WebSocket listener so I can send out near-realtime updates to subscribed browsers. It looks like this:
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();
All of those classes except for Listener
are part of Ratchet, and the Listener
is my handler implementation of \Ratchet\MessageComponentInterface
, which responds to the open/close/error events of connecting WebSockets.
I would like this script to be contactable by a queue system I am building, and since that is a system channel, I would like to expose this on a different port so that it is not reachable from the internet. This would ideally be on HTTP rather than WebSocket; I have successfully used a PHP WebSocket client to contact this listener, but that's a bit complicated compared to a file_get_contents('http://...')
call!
At a guess, the internal loop of React (e.g. StreamSelectLoop::streamSelect
) only blocks for short time (see here) so it feels possible that it could manage a number of separate streams internally. Ideally, I would like the additional port to be handled by a separate listener, for security isolation (in case it is possible for a flaw in Guzzle to allow an attacker to appear to come from the restricted port when in fact they came from the internet port).
I think this is not an unusual requirement, but there does not seem to be any related information in the docs, and the GitHub issues are rather bare here too. Is this configuration possible without setting up parallel processes or multithreading?
One solution to this problem is to add IP whitelisting in the WebSocket listener for specific message types. I may do that in the short term, but listening on another port would be much nicer solution.