【问题标题】:Swiftmailer not sending immediatelySwiftmailer 没有立即发送
【发布时间】:2015-04-22 15:28:52
【问题描述】:

我已成功配置我的 symfony webapp 以使用 SMTP 发送电子邮件。但是我所有的发送电子邮件都被放入了spool 目录。

这应该只发生在发送错误的情况下。对吗?

但是如果我执行命令swiftmailer:spool:send --env=prod,我所有的电子邮件都会正确发送。

为什么我的服务器没有立即发送电子邮件? 那是因为我修复了错误吗?有没有办法解决这个问题?

swiftmailer:

spool:
    type: file
    path: %kernel.root_dir%/spool

【问题讨论】:

    标签: symfony configuration ubuntu-14.04 swiftmailer


    【解决方案1】:

    只需将命令swiftmailer:spool:send 添加到crontab 中。这一步在Symfony documentation上不清楚。

    【讨论】:

      【解决方案2】:

      如果有人通过消息队列(symfony/messenger)处理电子邮件,使用内存假脱机是首选选项。但是,内存假脱机仅在 Kernel::terminate 事件上处理。此事件永远不会在长时间运行的控制台工作程序上发生。

      此内核事件正在调用Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener::onTerminate() 方法。您可以通过调度您自己的事件并订阅上述方法来手动调用此方法。

      src/App/Email/Events.php

      <?php
      
      namespace App\Email;
      
      class Events
      {
          public const UNSPOOL = 'unspool';
      }
      

      config/services.yml

      services:    
          App\Email\AmqpHandler:
            tags: [messenger.message_handler]
      
          Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener:
              tags:
                  - name: kernel.event_listener
                    event: !php/const App\Email\Events::UNSPOOL
                    method: onTerminate
      

      你的消息队列工作者 src/App/Email/AmqpHandler.php

      <?php
      
      namespace App\Email;
      
      use Symfony\Component\EventDispatcher\EventDispatcherInterface;
      
      class AmqpHandler
      {
          /** @var EventDispatcherInterface */
          private $eventDispatcher;
      
          /** @var Swift_Mailer */
          private $mailer;
      
          public function __construct(EventDispatcherInterface $eventDispatcher, Swift_Mailer $mailer)
          {
              $this->eventDispatcher = $eventDispatcher;
              $this->mailer = $mailer;
          }
      
          public function __invoke($emailMessage): void
          {
              //...
              $message = (new Swift_Message($subject))
                  ->setFrom($emailMessage->from)
                  ->setTo($emailMessage->to)
                  ->setBody($emailMessage->body, 'text/html');
      
              $successfulRecipientsCount = $this->mailer->send($message, $failedRecipients);
              if ($successfulRecipientsCount < 1 || count($failedRecipients) > 0) {
                  throw new DeliveryFailureException($message);
              }
      
              $this->eventDispatcher->dispatch(Events::UNSPOOL);
          }
      }
      

      您可以阅读 symfony/messenger here

      【讨论】:

        【解决方案3】:

        您可以强制冲洗阀芯。 例如:

        $mailer = $this->container->get('mailer');
        $mailer->send($message);
        
        $spool = $mailer->getTransport()->getSpool();
        $transport = $this->container->get('swiftmailer.transport.real');
        if ($spool and $transport) $spool->flushQueue($transport);
        

        还要检查 config.yml 中的假脱机配置。

        如果你有:

        swiftmailer:
            ....
            spool:     { type: memory }
        

        在内核终止事件上发送邮件(所以在页面末尾)

        【讨论】:

        • 是的,在某些情况下我会这样做。但是当FOSUserBundle 发送电子邮件时,队列不会被刷新。我使用 spool typy 作为file。所以只有在我手动刷新时才会发送电子邮件。在我的旧机器上,这是自动完成的。
        • 你不想使用内存? (至少对于 FOSUserBundle)
        • 为什么使用filememory
        • 查看symfony.com/doc/current/cookbook/email/spool.html 的开头以获得文件假脱机的优势(但您必须刷新...)
        • 是的。现在我不明白了。我正在从其他人配置的机器进行迁移,所以这是我第一次从零开始配置 Symfony。目前尚不清楚您是否应该将命令添加到 cron 选项卡以发送电子邮件。
        猜你喜欢
        • 2018-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-27
        • 2019-11-29
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多