【问题标题】:Symfony messenger and mailer : how to add a binding_key?Symfony messenger 和 mailer:如何添加 binding_key?
【发布时间】:2021-01-29 01:06:09
【问题描述】:

我有一个使用 messenger 和 rabbitMQ 正在运行的 Symfony 4.4 项目。 我有一个带有 2 个队列的异步传输。

    transports:
        # https://symfony.com/doc/current/messenger.html#transport-configuration
      async:
        dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
        options:
          exchange:
            name: myexchange
            type: direct
          queues:
            email:
              binding_keys:
                - email
            extranet:
              binding_keys:
                  - extranet
        # failed: 'doctrine://default?queue_name=failed'
        # sync: 'sync://'

    routing:
        # Route your messages to the transports
        'App\Message\ExtranetMessage': async
        'Symfony\Component\Mailer\Messenger\SendEmailMessage': async

我需要将带有symfony/mailer 组件的电子邮件发送到电子邮件队列。

public function contact(Request $request, MailerInterface $mailer)
{
    if($request->isXmlHttpRequest())
    {
        //dd($request->request->all());
        $body =
            'Nouveau message depuis le front<br />
             Nom = '.$request->request->get('nom').'<br />
             Prénom = '.$request->request->get('prenom').'<br />
             Société = '.$request->request->get('societe').'<br />
             Email = '.$request->request->get('mail').'<br />';

        $email = (new Email())
            ->from('from@email.tld')
            ->replyTo($request->request->get('mail'))
            ->to('$request->request->get('mail')')
            ->subject('test')
            ->html($body);

        $mailer->send($email);

        return new JsonResponse('OK', 200);
    }
}

如何将 binding_key 添加到 mailer 以便让 rabbitMQ 知道如何处理电子邮件?

【问题讨论】:

    标签: symfony rabbitmq symfony4 symfony-messenger symfony-mailer


    【解决方案1】:

    或者,您可以使用不同的交换名称为每个队列定义单独的传输。

        transports:
          async_email:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            options:
              exchange:
                name: messages_email
              queues:
                email: ~
          async_extranet:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            options:
              exchange:
                name: messages_extranet
              queues:
                extranet: ~
    
        routing:
            'App\Message\ExtranetMessage': async_extranet
            'Symfony\Component\Mailer\Messenger\SendEmailMessage': async_email
    

    在这种情况下,您不需要在每个消息派发时指定绑定键或创建自定义中间件。

    【讨论】:

      【解决方案2】:

      可以指定路由键via stamps。不幸的是,邮件程序集成没有公开添加它们的方法,它只是将消息分派到默认队列。但您仍然可以手动发送消息:

      $this->dispatchMessage(new SendEmailMessage($email), [new AmqpStamp('email')]);
      

      这种方法有一些限制:由于这没有使用mailer 代码,MessageEvent 将不会被分派,并且分析器中的“电子邮件”窗格将为空。

      另一种选择是使用中间件添加标记:

      1. 创建中间件
      // src/Messenger/StampEmailMessageMiddleware.php
      class StampEmailMessageMiddleware implements MiddlewareInterface
      {
          const bindingKey = 'email';
      
          public function handle(Envelope $envelope, StackInterface $stack): Envelope
          {
              // Add the stamp. Since the middleware gets called both when dispatching and 
              // consuming the message, we make sure there's no stamp already added.
              if (
                  $envelope->getMessage() instanceof SendEmailMessage && 
                  null === $envelope->last(AmqpStamp::class)
              ) {
                  $envelope = $envelope->with(new AmqpStamp(self::bindingKey));
              }
      
              return $stack->next()->handle($envelope, $stack);
          }
      }
      
      
      1. 将中间件添加到总线配置中:
      # config/packages/messenger.yaml
      messenger:
          buses:
              messenger.bus.default:
                  middleware:
                      - 'App\Messenger\StampEmailMessageMiddleware'
      
      
      1. 正常发送消息:
      $mailer->send($email);
      

      【讨论】:

        【解决方案3】:

        好的,我在搜索完整的Messenger配置参考时找到了答案。

        为了在没有绑定键的情况下处理消息,必须添加一个default_publish_routing_key 条目。 配置现在看起来像:

            transports:
                # https://symfony.com/doc/current/messenger.html#transport-configuration
              async:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                options:
                  exchange:
                    name: myexchange
                    type: direct
                    default_publish_routing_key: email
                  queues:
                    email:
                      binding_keys:
                        - email
                    extranet:
                      binding_keys:
                          - extranet
                # failed: 'doctrine://default?queue_name=failed'
                # sync: 'sync://'
        
            routing:
                # Route your messages to the transports
                'App\Message\ExtranetMessage': async
                'Symfony\Component\Mailer\Messenger\SendEmailMessage': async
        

        这允许信使组件在没有指定任何队列的情况下处理消息事件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-10-06
          • 2019-11-30
          • 2021-10-02
          • 2014-08-31
          • 2020-07-18
          • 2020-06-05
          • 1970-01-01
          相关资源
          最近更新 更多