【问题标题】:Can we dispatch an event from Rabbitmq Consumer in Symfony 4.3?我们可以在 Symfony 4.3 中从 Rabbitmq Consumer 发送事件吗?
【发布时间】:2020-01-08 22:33:54
【问题描述】:

我正在尝试从 Rabbitmq 消费者分派一个自定义事件。这个过程曾经在 Symfony 3.4 上工作,最近将该项目升级到 Symfony Flex(4.3)。

DatasetSubmissionConsumer.php

use OldSound\RabbitMqBundle\RabbitMq\ConsumerInterface;

/**
 * A consumer of dataset submission messages.
 *
 * @see ConsumerInterface
 */
class DatasetSubmissionConsumer implements ConsumerInterface
{

    /**
     * The entity event dispatcher.
     *
     * @var EntityEventDispatcher
     */
    protected $entityEventDispatcher;

    /**
     * Constructor.
     *
     * @param EntityEventDispatcher  $entityEventDispatcher The entity event dispatcher.
     */
    public function __construct(
        EntityEventDispatcher $entityEventDispatcher,
    ) {
        $this->entityEventDispatcher = $entityEventDispatcher;
    }

    /**
     * Process a filer message.
     *
     * @param AMQPMessage $message A filer message.
     *
     * @return boolean True if success, false otherwise.
     */
    public function execute(AMQPMessage $message)
    {
        $datasetSubmissionId = $message->body;

        // Do Something //
        $this->entityEventDispatcher->dispatch($datasetSubmission, 'dataset_processed');
        return true;
    }
}

DatasetSubmissionListener.php

/**
 * Listener class for Dataset Submission-related events.
 */
class DatasetSubmissionListener 
{
      /**
     * Method to send an email to DRPM on a dataset_processed event.
     *
     * @param EntityEvent $event Event being acted upon.
     *
     * @return void
     */
    public function onDatasetProcessed(EntityEvent $event)
    {
        $datasetSubmission = $event->getEntity();

        // Added if-statement so that emails are sent to data-managers only 
        // Do Something and send Email
    }
}

EntityEventDispatcher.php

<?php

namespace App\Event;

use Symfony\Component\EventDispatcher\EventDispatcherInterface;


/**
 * An entity event dispatcher.
 */
class EntityEventDispatcher
{
    /**
     * The event dispatcher to use in this entity event dispatcher.
     *
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    /**
     * Constructor.
     *
     * @param EventDispatcherInterface $eventDispatcher The event dispatcher to use.
     */
    public function __construct(EventDispatcherInterface $eventDispatcher)
    {
        $this->eventDispatcher = $eventDispatcher;
    }

    /**
     * Dispatch an Entity event.
     *
     * @param Entity $entity          The Entity the event is for.
     * @param string $entityEventName The name of the entity event.
     *
     * @return void
     */
    public function dispatch(Entity $entity, string $entityEventName)
    {
        $this->eventDispatcher->dispatch(
            'pelagos.entity.' . $entity->getUnderscoredName() . '.' . $entityEventName,
            new EntityEvent($entity)
        );
    }
}
App\Event\DatasetSubmissionListener:
        tags:
            - { name: kernel.event_listener, event: pelagos.entity.dataset_submission.dataset_processed, method: onDatasetProcessed }

还运行了bin/console debug:event-dispatcher,并且该事件是可调用的

"pelagos.entity.dataset_submission.dataset_processed" event
-----------------------------------------------------------

 ------- ----------------------------------------------------------- ---------- 
  Order   Callable                                                    Priority  
 ------- ----------------------------------------------------------- ---------- 
  #1      App\Event\DatasetSubmissionListener::onDatasetProcessed()   0         
 ------- ----------------------------------------------------------- ---------- 

使用 Symfony 4.3、Rabbitmq 3.3.5

在 Rabbitmq 消费者成功退出后,事件侦听器不会捕获此分派事件。有没有办法调试或使它工作?

谢谢。

【问题讨论】:

    标签: symfony rabbitmq symfony4 symfony-flex symfony-eventdispatcher


    【解决方案1】:

    我发现我们可以从 Rabbitmq Consumer 分派事件。问题在于 SwiftMailer 没有从事件侦听器中的已调度事件发送电子邮件。

    DatasetSubmissionListener.php

    /**
     * Listener class for Dataset Submission-related events.
     */
    class DatasetSubmissionListener 
    {
          /**
         * Method to send an email to DRPM on a dataset_processed event.
         *
         * @param EntityEvent $event Event being acted upon.
         *
         * @return void
         */
        public function onDatasetProcessed(EntityEvent $event)
        {
            $datasetSubmission = $event->getEntity();
    
            // Added if-statement so that emails are sent to data-managers only 
            // Do Something and send Email
           sendEmailMessage($this->twig->load('Email/data-repository-managers.dataset-processed.email.twig'), $this->tokenStorage->getToken()->getUser());
        }
    
            /**
         * Method to build and send an email.
         *
         * @param \Twig\TemplateWrapper $emailTwigTemplate A twig template.
         * @param array                 $mailData          Mail data array for email.
         * @param array                 $toAddresses       Recipient's email addresses.
         * @param array                 $attachments       An optional array of Swift_Message_Attachments to attach.
         *
         * @throws \InvalidArgumentException When any element of $attachments is not a Swift_Message_Attachment.
         *
         * @return void
         */
        public function sendEmailMessage(
            \Twig\TemplateWrapper $emailTwigTemplate,
            array $mailData,
            array $toAddresses = array(),
            array $attachments = array()
        ) {
             $message = new \Swift_Message();
             $message
                ->setSubject($emailTwigTemplate->renderBlock('subject', $mailData))
                ->setFrom($this->from)
                ->setTo($toAddresses)
                ->setBody($emailTwigTemplate->renderBlock('body_html', $mailData), 'text/html')
                ->addPart($emailTwigTemplate->renderBlock('body_text', $mailData), 'text/plain');
            foreach ($attachments as $attachment) {
                if (!$attachment instanceof \Swift_Attachment) {
                    throw new \InvalidArgumentException('Attachment is not an instance of Swift_Attachment');
                }
                $message->attach($attachment);
            }
    
            $this->mailer->send($message);
        }
    }
    

    我之前对 swiftmailer 的配置:

    swiftmailer:
        url: '%env(MAILER_URL)%'
        transport: sendmail
        spool:     { type: memory }
    

    当我启用假脱机功能时,swiftmailer 正在等待 对于来自 Rabbitmq 消费者的内核终止事件,以及 消费者在确认消息后不会被终止

    为了解决这个问题,我所做的只是移除了假脱机功能。

    swiftmailer:
        url: '%env(MAILER_URL)%'
        transport: sendmail
    

    【讨论】:

      猜你喜欢
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2023-03-03
      相关资源
      最近更新 更多