Symfony Messenger 中没有配置处理程序
No configured handlers in Symfony Messenger
我想实现 Messenger 异步处理程序并能够在 Redis 中对一些任务进行排队,但由于某些原因我不能。
这是我的全局配置:
- PHP 7.3.16
- Symfony 4.4.7
- 信使 4.4
- Redis 5.0.3
- Predis 1.1
我试着遵循这个指南:
https://symfony.com/doc/4.4/messenger.html
一切都是来自文档的 copy/paste,除了我用命令替换了我的控制器。
这个调度命令似乎有效:
php bin/console app:dispatch-command
^ Symfony\Component\Messenger\Envelope^ {#5465 -stamps: []
-message: App\Message\SmsNotification^ {#5475
-content: "Look! I created a message!" } }
这个命令returns没有配置处理程序:
php bin/console debug:messenger
Messenger
=========
第二个命令returns在尝试使用消息时出错
php bin/console messenger:consume async
TypeError {#174
#message: "The first argument must be an instance of "Symfony\Component\Messenger\RoutableMessageBus"."
#code: 0
#file: "./vendor/symfony/messenger/Command/ConsumeMessagesCommand.php"
#line: 54
trace: {
./vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:54 { …}
./var/cache/dev/ContainerM8fc2IB/srcApp_KernelDevDebugContainer.php:3736 {
ContainerM8fc2IB\srcApp_KernelDevDebugContainer->getConsole_Command_MessengerConsumeMessagesService()^
›
› $this->privates['console.command.messenger_consume_messages'] = $instance = new \Symfony\Component\Messenger\Command\ConsumeMessagesCommand('', ($this->privates['messenger.receiver_locator'] ?? ($this->privates['messenger.receiver_locator'] = new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($this->getService, [], []))), ($this->services['event_dispatcher'] ?? $this->getEventDispatcherService()), ($this->privates['monolog.logger.messenger'] ?? $this->getMonolog_Logger_MessengerService()), []);
›
arguments: {
$routableBus: ""
$receiverLocator: Symfony\Component\DependencyInjection\Argument\ServiceLocator {#178 …}
$eventDispatcher: Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher {#188 …}
$logger: Symfony\Bridge\Monolog\Logger {#179 …}
$receiverNames: []
}
}
./vendor/symfony/dependency-injection/Container.php:450 { …}
./vendor/symfony/dependency-injection/Argument/ServiceLocator.php:40 { …}
./vendor/symfony/console/CommandLoader/ContainerCommandLoader.php:45 { …}
./vendor/symfony/console/Application.php:541 { …}
./vendor/symfony/console/Application.php:634 { …}
./vendor/symfony/framework-bundle/Console/Application.php:117 { …}
./vendor/symfony/console/Application.php:235 { …}
./vendor/symfony/framework-bundle/Console/Application.php:83 { …}
./vendor/symfony/console/Application.php:147 { …}
./bin/console:42 { …}
}
}
2020-04-20T20:08:02+02:00 [critical] Uncaught Error: The first argument must be an instance of "Symfony\Component\Messenger\RoutableMessageBus".
这里有一些相关文件...
# .env
MESSENGER_TRANSPORT_DSN=redis://127.0.0.1:6379/messages/?auto_setup=true&serializer=1&stream_max_entries=0&dbindex=0
# config/packages/messenger.yaml
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
'App\Message\SmsNotification': async
# config/services.yaml
parameters:
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
<?php
// src/Message/SmsNotification.php
namespace App\Message;
class SmsNotification
{
private $content;
public function __construct(string $content)
{
$this->content = $content;
}
public function getContent(): string
{
return $this->content;
}
}
<?php
// src/MessageHandler/SmsNotificationHandler.php
namespace App\MessageHandler;
use App\Message\SmsNotification;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class SmsNotificationHandler implements MessageHandlerInterface
{
public function __invoke(SmsNotification $message)
{
dump('ok!');
echo('handler');
}
}
<?php
// src/Command/DispatchCommand
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use App\Message\SmsNotification;
use Symfony\Component\Messenger\MessageBusInterface;
class DispatchCommand extends Command
{
protected $bus;
protected static $defaultName = 'app:dispatch-command';
public function __construct(MessageBusInterface $bus)
{
$this->bus = $bus;
}
protected function configure()
{
$this
->setDescription('Dispatch test command')
->setHelp('Dispatch test command');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$dispatch = $this->bus->dispatch(new SmsNotification('Look! I created a message!'));
dump($dispatch);
}
有人可以帮我吗?
干杯!
更新
我尝试按照 the doc 中的说明手动路由我的处理程序:
# config/services.yaml
App\MessageHandler\SmsNotificationHandler:
tags: [messenger.message_handler]
但这并没有改变什么。
我还检查了我的消息和消息处理程序是否已注册为服务,它是:
php bin/console debug:container App
[70 ] App\Message\SmsNotification
[71 ] App\MessageHandler\SmsNotificationHandler
我仍然不知道是什么原因导致了这个问题,但我刚刚通过安装一个全新的 Symfony 4.4.7 项目并覆盖它成功地解决了它。
我还发现 swiftmailer 已被 mailer 取代,twig-bundle 被 twig-pack 取代,但仅适用于新项目,而 composer 不会注意到现有安装(即使使用 composer update/upgrade/recipes。它可能是我遇到问题的原因,但我不确定。
第 1 步:创建一个新的 Symfony 4.4.7 项目
composer create-project symfony/website-skeleton newProj ^4.4.7
sudo chown -R $USER:www-data
cd /newProj
第 2 步:用我的 git 项目覆盖
git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master
第 3 步:安装供应商并替换过时的依赖项
composer install
composer remove symfony/swiftmailer
composer require symfony/mailer
composer remove symfony/twig-bundle
composer require symfony/twig-pack
第 4 步:检查 Messenger
$ php bin/console debug:messenger
Messenger
=========
messenger.bus.default
---------------------
The following messages can be dispatched:
----------------------------------------------------------
App\Message\SmsNotification
handled by App\MessageHandler\SmsNotificationHandler
Symfony\Component\Mailer\Messenger\SendEmailMessage
handled by mailer.messenger.message_handler
----------------------------------------------------------
这是我的实际 composer.json 文件
{
"type": "project",
"license": "proprietary",
"require": {
"php": "7.3.*",
"ext-ctype": "*",
"ext-iconv": "*",
"guzzlehttp/guzzle": "^6.5",
"impulze/intervention-image-bundle": "^1.2",
"laminas/laminas-code": "^3.4",
"laminas/laminas-eventmanager": "^3.2",
"nelmio/api-doc-bundle": "^3.6",
"predis/predis": "^1.1",
"sensio/framework-extra-bundle": "^5.1",
"symfony/asset": "4.4.*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/error-handler": "4.4.*",
"symfony/expression-language": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/form": "4.4.*",
"symfony/framework-bundle": "4.4.*",
"symfony/http-client": "4.4.*",
"symfony/intl": "4.4.*",
"symfony/mailer": "4.4.*",
"symfony/messenger": "4.4.*",
"symfony/monolog-bundle": "^3.1",
"symfony/orm-pack": "*",
"symfony/phpunit-bridge": "^5.0",
"symfony/process": "4.4.*",
"symfony/security-bundle": "4.4.*",
"symfony/serializer-pack": "*",
"symfony/translation": "4.4.*",
"symfony/twig-pack": "^1.0",
"symfony/validator": "4.4.*",
"symfony/web-link": "4.4.*",
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"sensiolabs/security-checker": "^6.0",
"symfony/debug-pack": "*",
"symfony/maker-bundle": "^1.0",
"symfony/profiler-pack": "*",
"symfony/test-pack": "*"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\Tests\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"security-checker security:check": "script"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}
我想实现 Messenger 异步处理程序并能够在 Redis 中对一些任务进行排队,但由于某些原因我不能。
这是我的全局配置:
- PHP 7.3.16
- Symfony 4.4.7
- 信使 4.4
- Redis 5.0.3
- Predis 1.1
我试着遵循这个指南:
https://symfony.com/doc/4.4/messenger.html
一切都是来自文档的 copy/paste,除了我用命令替换了我的控制器。
这个调度命令似乎有效:
php bin/console app:dispatch-command
^ Symfony\Component\Messenger\Envelope^ {#5465 -stamps: []
-message: App\Message\SmsNotification^ {#5475 -content: "Look! I created a message!" } }
这个命令returns没有配置处理程序:
php bin/console debug:messenger
Messenger
=========
第二个命令returns在尝试使用消息时出错
php bin/console messenger:consume async
TypeError {#174
#message: "The first argument must be an instance of "Symfony\Component\Messenger\RoutableMessageBus"."
#code: 0
#file: "./vendor/symfony/messenger/Command/ConsumeMessagesCommand.php"
#line: 54
trace: {
./vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:54 { …}
./var/cache/dev/ContainerM8fc2IB/srcApp_KernelDevDebugContainer.php:3736 {
ContainerM8fc2IB\srcApp_KernelDevDebugContainer->getConsole_Command_MessengerConsumeMessagesService()^
›
› $this->privates['console.command.messenger_consume_messages'] = $instance = new \Symfony\Component\Messenger\Command\ConsumeMessagesCommand('', ($this->privates['messenger.receiver_locator'] ?? ($this->privates['messenger.receiver_locator'] = new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($this->getService, [], []))), ($this->services['event_dispatcher'] ?? $this->getEventDispatcherService()), ($this->privates['monolog.logger.messenger'] ?? $this->getMonolog_Logger_MessengerService()), []);
›
arguments: {
$routableBus: ""
$receiverLocator: Symfony\Component\DependencyInjection\Argument\ServiceLocator {#178 …}
$eventDispatcher: Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher {#188 …}
$logger: Symfony\Bridge\Monolog\Logger {#179 …}
$receiverNames: []
}
}
./vendor/symfony/dependency-injection/Container.php:450 { …}
./vendor/symfony/dependency-injection/Argument/ServiceLocator.php:40 { …}
./vendor/symfony/console/CommandLoader/ContainerCommandLoader.php:45 { …}
./vendor/symfony/console/Application.php:541 { …}
./vendor/symfony/console/Application.php:634 { …}
./vendor/symfony/framework-bundle/Console/Application.php:117 { …}
./vendor/symfony/console/Application.php:235 { …}
./vendor/symfony/framework-bundle/Console/Application.php:83 { …}
./vendor/symfony/console/Application.php:147 { …}
./bin/console:42 { …}
}
}
2020-04-20T20:08:02+02:00 [critical] Uncaught Error: The first argument must be an instance of "Symfony\Component\Messenger\RoutableMessageBus".
这里有一些相关文件...
# .env
MESSENGER_TRANSPORT_DSN=redis://127.0.0.1:6379/messages/?auto_setup=true&serializer=1&stream_max_entries=0&dbindex=0
# config/packages/messenger.yaml
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
'App\Message\SmsNotification': async
# config/services.yaml
parameters:
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
<?php
// src/Message/SmsNotification.php
namespace App\Message;
class SmsNotification
{
private $content;
public function __construct(string $content)
{
$this->content = $content;
}
public function getContent(): string
{
return $this->content;
}
}
<?php
// src/MessageHandler/SmsNotificationHandler.php
namespace App\MessageHandler;
use App\Message\SmsNotification;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class SmsNotificationHandler implements MessageHandlerInterface
{
public function __invoke(SmsNotification $message)
{
dump('ok!');
echo('handler');
}
}
<?php
// src/Command/DispatchCommand
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use App\Message\SmsNotification;
use Symfony\Component\Messenger\MessageBusInterface;
class DispatchCommand extends Command
{
protected $bus;
protected static $defaultName = 'app:dispatch-command';
public function __construct(MessageBusInterface $bus)
{
$this->bus = $bus;
}
protected function configure()
{
$this
->setDescription('Dispatch test command')
->setHelp('Dispatch test command');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$dispatch = $this->bus->dispatch(new SmsNotification('Look! I created a message!'));
dump($dispatch);
}
有人可以帮我吗?
干杯!
更新
我尝试按照 the doc 中的说明手动路由我的处理程序:
# config/services.yaml
App\MessageHandler\SmsNotificationHandler:
tags: [messenger.message_handler]
但这并没有改变什么。
我还检查了我的消息和消息处理程序是否已注册为服务,它是:
php bin/console debug:container App
[70 ] App\Message\SmsNotification
[71 ] App\MessageHandler\SmsNotificationHandler
我仍然不知道是什么原因导致了这个问题,但我刚刚通过安装一个全新的 Symfony 4.4.7 项目并覆盖它成功地解决了它。
我还发现 swiftmailer 已被 mailer 取代,twig-bundle 被 twig-pack 取代,但仅适用于新项目,而 composer 不会注意到现有安装(即使使用 composer update/upgrade/recipes。它可能是我遇到问题的原因,但我不确定。
第 1 步:创建一个新的 Symfony 4.4.7 项目
composer create-project symfony/website-skeleton newProj ^4.4.7
sudo chown -R $USER:www-data
cd /newProj
第 2 步:用我的 git 项目覆盖
git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master
第 3 步:安装供应商并替换过时的依赖项
composer install
composer remove symfony/swiftmailer
composer require symfony/mailer
composer remove symfony/twig-bundle
composer require symfony/twig-pack
第 4 步:检查 Messenger
$ php bin/console debug:messenger
Messenger
=========
messenger.bus.default
---------------------
The following messages can be dispatched:
----------------------------------------------------------
App\Message\SmsNotification
handled by App\MessageHandler\SmsNotificationHandler
Symfony\Component\Mailer\Messenger\SendEmailMessage
handled by mailer.messenger.message_handler
----------------------------------------------------------
这是我的实际 composer.json 文件
{
"type": "project",
"license": "proprietary",
"require": {
"php": "7.3.*",
"ext-ctype": "*",
"ext-iconv": "*",
"guzzlehttp/guzzle": "^6.5",
"impulze/intervention-image-bundle": "^1.2",
"laminas/laminas-code": "^3.4",
"laminas/laminas-eventmanager": "^3.2",
"nelmio/api-doc-bundle": "^3.6",
"predis/predis": "^1.1",
"sensio/framework-extra-bundle": "^5.1",
"symfony/asset": "4.4.*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/error-handler": "4.4.*",
"symfony/expression-language": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/form": "4.4.*",
"symfony/framework-bundle": "4.4.*",
"symfony/http-client": "4.4.*",
"symfony/intl": "4.4.*",
"symfony/mailer": "4.4.*",
"symfony/messenger": "4.4.*",
"symfony/monolog-bundle": "^3.1",
"symfony/orm-pack": "*",
"symfony/phpunit-bridge": "^5.0",
"symfony/process": "4.4.*",
"symfony/security-bundle": "4.4.*",
"symfony/serializer-pack": "*",
"symfony/translation": "4.4.*",
"symfony/twig-pack": "^1.0",
"symfony/validator": "4.4.*",
"symfony/web-link": "4.4.*",
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"sensiolabs/security-checker": "^6.0",
"symfony/debug-pack": "*",
"symfony/maker-bundle": "^1.0",
"symfony/profiler-pack": "*",
"symfony/test-pack": "*"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\Tests\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"security-checker security:check": "script"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}