如何将参数传入 Websocket 处理程序? [英] How to arguments into the Websocket handler?

查看:45
本文介绍了如何将参数传入 Websocket 处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个记分卡应用程序,其中某些成员正在玩,并且可以在图表中更新他们的分数,这也需要反映在团队成员屏幕中.

I am developing a scorecard application where certain group of members are playing and can update their score in chart which needs to be reflected in team members screen too.

为此,我使用了 cboden/ratchet.

每个团队都有一个通用的团队代码,我将使用 URL localhost:8000/{token} 传递该代码,该代码将从控制器传递到 twig.

Each team have a common team code which I will pass using URL localhost:8000/{token} which will be passed from controller to twig.

我有以下命令:

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

ScoreHandler

public function __construct(EntityManagerInterface $entityManager)
{
    $this->connections = new SplObjectStorage;
    $this->entityManager = $entityManager;
}

这会返回我 函数 App\Websocket\ScoreHandler::__construct() 的参数太少,0 传递 错误.

我不知道如何在此处修复此错误.因为我打算插入数据库并根据令牌获取记录并返回到某个用户组.

I am not sure how to fix this error here. As I am planning to insert into the db and fetch records based on token and return to certain user group.

有人可以帮我吗?

推荐答案

注意事项

强烈建议不要将 PHP 与 Symfony 和/或 Doctrine 用于任何长时间运行的后台进程(守护进程),它侦听 WebSocket(或其他)连接,在任何生产/现实世界中使用 Ratchet/ReactPHP 风格的功能环境.PHP 并非设计为作为守护程序运行.因此,如果没有适当的计划,该过程将因 Doctrine Connection 异常和 MySQL Server Has Gone Away 错误或由维护实体管理器、Symfony 服务定义和记录器溢出而导致的内存泄漏而崩溃.

Word of Caution

It is strongly discouraged from using PHP with Symfony and/or Doctrine for any long-running background processes (daemon), that listens for WebSocket (or other) connections, using Ratchet/ReactPHP style features in any production/real-world environments. PHP was not designed to run as a daemon. As such, without proper planning, the process will crash with either a Doctrine Connection exception with the MySQL Server Has Gone Away error or from memory leaks caused by maintaining the Entity Manager, Symfony service definitions and logger overflows.

使用 PHP 作为守护进程需要实施不直观的解决方法,例如 Messenger Queue(导致响应之间的长时间延迟)或 Lazy Proxy 对象(导致代码-级别的可维护性问题)和额外的后台进程,例如主管和/或 cron 作业,以规避固有问题并从崩溃中恢复.

Using PHP as a daemon would require implementing unintuitive workarounds, such as a Messenger Queue (causes long delays between responses) or Lazy Proxy objects (causes code-level maintainability issues) and additional background processes, like supervisor and/or cron jobs to circumvent the inherent issues and recover from crashes.

如果您为 config/services.yaml 使用默认的 autowire 配置并且 ScoreHandler 不在排除路径之一中,则使用依赖项可以使用以下选项注射.

Provided you are using the default autowire configuration for your config/services.yaml and ScoreHandler is not in one of the excluded paths, the following options are feasible using dependency injection.

# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

    # ...

ScoreHandler 作为服务注入

推荐的方法是在命令中注入ScoreHandler服务,这样也会自动将EntityManagerInterface注入ScoreHandler.>

Inject ScoreHandler as a Service

The recommended approach is to inject the ScoreHandler service into the command, which will also automatically inject the EntityManagerInterface into the ScoreHandler.

class YourCommand extends Command
{

    private $handler;

    public function __construct(ScoreHandler $handler)
    {
        $this->handler = $handler;
        parent::__construct();
    }

    //...

    public function execute(InputInterface $input, OutputInterface $outpu)
    {

        //...

        $server = IoServer::factory(
            new HttpServer(
                new WsServer($this->handler)
            ),
            8080
        );
        $server->run();
    }
}

注入EntityManagerInterface并传递给ScoreHandler

由于您要手动创建 ScoreHandler 的新实例,因此需要将 EntityManagerInterface 作为参数提供给构造函数.

Inject EntityManagerInterface and pass to ScoreHandler

Since you are creating a new instance of ScoreHandler manually, it requires the EntityManagerInterface to be supplied as an argument to the constructor.

不推荐这样做,因为已经存在一个服务,并且如前一个示例中那样已经自动装配.

This is not recommended, as a service already exists that is already autowired as in the previous example.

class YourCommand extends Command
{

    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
        parent::__construct();
    }

    //...

    public function execute(InputInterface $input, OutputInterface $outpu)
    {

        //...

        $server = IoServer::factory(
            new HttpServer(
                new WsServer(
                    new ScoreHandler($this->em)
                )
            ),
            8080
        );
        $server->run();
    }
}


NodeJS 替代方案

虽然 PHP 不是作为守护进程设计的,但 nodejs 和其他几个平台能够促进连接监听.它们可用于将请求转发到您的 Symfony Web 应用程序并将响应发送回客户端,作为请求代理.


NodeJS Alternative

While PHP was not designed as a daemon, nodejs and several other platforms are able to facilitate listening for connections. They can be used to forward the request to your Symfony web application and send a response back to the client, as a request broker.

请参阅 https://stackoverflow.com/a/68027150/1144627,了解 WebSocket 代理服务的示例.

See https://stackoverflow.com/a/68027150/1144627 for an example of a WebSocket Broker Service.

这篇关于如何将参数传入 Websocket 处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆