du5910 2017-07-28 09:04
浏览 58

Ratchet / ReactPHP循环可以监听多个端口吗?

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.

  • 写回答

1条回答 默认 最新

  • dpfps86064 2017-07-28 09:33
    关注

    I found one way, it may be not a best practice, but you can manually add socket, like this:

    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();
    
    评论

报告相同问题?

悬赏问题

  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来