如何将参数传入 Websocket 处理程序?
How to arguments into the Websocket handler?
我正在开发一个记分卡应用程序,其中特定组的成员正在玩并且可以在图表中更新他们的分数,这也需要反映在团队成员屏幕中。
为此,我使用 cboden/ratchet
。
每个团队都有一个共同的团队代码,我将使用 URL localhost:8000/{token}
将其从控制器传递到 twig。
我有以下命令:
$server = IoServer::factory(
new HttpServer(
new WsServer(
new ScoreHandler()
)
),
8080
);
$server->run();
得分处理程序
public function __construct(EntityManagerInterface $entityManager)
{
$this->connections = new SplObjectStorage;
$this->entityManager = $entityManager;
}
这 return 是我 Too few arguments to function App\Websocket\ScoreHandler::__construct(), 0 passed
的错误。
我不确定如何在此处修复此错误。因为我打算插入数据库并根据令牌和 return 向特定用户组获取记录。
有人可以帮我吗?
注意事项
强烈建议不要将 PHP 与 Symfony and/or Doctrine 一起用于任何监听 WebSocket(或其他)连接的长运行ning 后台进程(守护进程),在任何 production/real-world 环境中使用 Ratchet/ReactPHP 样式功能。 PHP 并非旨在 运行 作为守护程序。因此,如果没有适当的计划,该进程将因 MySQL Server Has Gone Away 错误的 Doctrine Connection 异常或维护实体管理器导致的内存泄漏而崩溃, Symfony 服务定义和记录器溢出。
使用 PHP 作为守护进程需要实施不直观的解决方法,例如 Messenger Queue (causes long delays between responses) or Lazy Proxy objects(导致代码级可维护性问题)和其他后台进程,例如主管 and/or cron 作业规避固有问题并从崩溃中恢复。
如果您为 config/services.yaml 使用默认的 autowire
配置并且 ScoreHandler
不在排除的路径之一中,则使用依赖项注入可以使用以下选项。
# 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
.
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
作为参数提供给构造函数。
不推荐这样做,因为已经存在一个服务,它已经像前面的示例一样自动装配。
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 网络应用程序并将响应发送回客户端,作为请求代理。
有关 WebSocket 代理服务的示例,请参阅 。