Symfony 5 Messenger не настраивает обработчик сообщений автоматически

Я новичок в платформе Symfony и пытаюсь создать проект с помощью Messenger (https://symfony.com/doc/current/messenger.html). Насколько я понимаю, после настройки класса обработчика с «реализует MessageHandlerInterface» обработчик должен быть доступен для использования, но, похоже, он не работает для меня. Я пробовал несколько разных вещей, включая создание нового проекта с нуля. Я использую Symfony 5.0.4.

Я настроил проект так:

symfony new --full testMessenger
composer require messenger
php bin/console make:controller

Затем я сделал новый мессенджер и обработчик и вызвал его из контроллера. При этом я получаю исключение: «Нет обработчика для сообщения« Приложение \ Сообщение \ Сообщение ».»

php bin/console debug:messenger

Выход:

Messenger 
========= 

messenger.bus.default 
--------------------- 

The following messages can be dispatched: 

-----------------------------------------------------  
 Symfony\Component\Mailer\Messenger\SendEmailMessage   
     handled by mailer.messenger.message_handler       
 Symfony\Component\Notifier\Message\ChatMessage        
     handled by chatter.messenger.chat_handler         
 Symfony\Component\Notifier\Message\SmsMessage         
     handled by texter.messenger.sms_handler           
-----------------------------------------------------  

Мой код в основном такой же, как образцы в документации обработчика сообщений, но я добавлю его сюда.

// src/Message.php
<?php

namespace App\Message;

class Message
{
    private $content;

    public function __construct(string $content)
    {
        $this->content = $content;
    }

    public function getContent(): string
    {
        return $this->content;
    }
}


// src/MessageHandler.php
<?php

namespace App\MessageHandler;

use App\Message\Message;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class SmsNotificationHandler implements MessageHandlerInterface
{
    public function __invoke(Message $message)
    {
        // ... do some work - like sending an SMS message!
    }
}


// src/Controller/MessageController.php
<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use App\Message\Message;

class MessageController extends AbstractController
{
    /**
     * @Route("/message", name="message")
     */
    public function index()
    {
        $this->dispatchMessage(new Message('Look! I created a message!'));

        return $this->render('message/index.html.twig', [
            'controller_name' => 'MessageController',
        ]);
    }
}




//config/packages/messenger.yaml

    framework:

    messenger:
        # Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
        # failure_transport: failed

        transports:
            # https://symfony.com/doc/current/messenger.html#transport-configuration
            # async: '%env(MESSENGER_TRANSPORT_DSN)%'
            # failed: 'doctrine://default?queue_name=failed'
            # sync: 'sync://'

        routing:
            # Route your messages to the transports
            # 'App\Message\YourMessage': async

person user1404617    schedule 01.02.2020    source источник
comment
Не могли бы вы также добавить конфигурацию Messenger?   -  person qdequippe    schedule 03.02.2020
comment
@qdequippe Я добавляю содержимое config / packages / messenger.yaml.   -  person user1404617    schedule 04.02.2020
comment
Спасибо. Я вижу // src / MessageHandler.php, но имя вашего класса - SmsNotificationHandler. Есть ли опечатка?   -  person qdequippe    schedule 04.02.2020
comment
@qdequippe Это была опечатка. Спасибо, что указали на это. Казалось, это ничего не меняет, но я понял, что это было. Пространства имен должны точно соответствовать структуре каталогов. Я поместил классы в папку src, сохранив пространство имен из примера. Это интересно, потому что этого не должно быть в исходном проекте, где у меня были эти проблемы. Я внимательно рассмотрю это на предмет проблем с пространством имен.   -  person user1404617    schedule 04.02.2020


Ответы (1)


Я немного боролся с подобным случаем, поэтому надеюсь, что это кому-то поможет:

Итак, у меня была включена автоматическая проводка и несколько шин были определены следующим образом:

final class QueryBus implements QueryBusInterface
{
    use HandleTrait {
        HandleTrait::handle as messengerHandle;
    }

    public function __construct(MessageBusInterface $messageBus)
    {
        $this->messageBus = $messageBus;
    }

    public function handle(object $query): mixed
    {
        return $this->messengerHandle($query);
    }
}

final class CommandBus implements CommandBusInterface
{
    use HandleTrait;

    public function __construct(
        MessageBusInterface $messageBus
    ) {
        $this->messageBus = $messageBus;
    }

    public function dispatch(object $command)
    {
        return $this->handle($command);
    }
}
// messenger.yaml
framework:
    messenger:

        default_bus: command_bus
        buses:
            command_bus: ~
            query_bus: ~

И у меня такая же ошибка при отправке запроса Нет обработчика сообщения ...

В конце концов, помогли:

  1. Отключите автоматическое подключение в каталогах реализации шины (исключив пути в services.yaml.
    App\:
        resource: '../src/'
        exclude:
            - '../src/Bus/'

  1. Определите службы вручную:
// services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

    App\src\Bus\CommandBus:
        arguments:
            - '@command_bus'

    App\src\Bus\QueryBus:
        arguments:
            - '@query_bus'

Так что на самом деле кажется, что это проблема с автоматическим подключением - не удалось выполнить автоматическое подключение двух реализаций одного и того же интерфейса (MessageBusInterface). Фактическая ошибка отсутствия сервиса скрывалась под компонентом мессенджера.

person Julius    schedule 22.01.2021