Swiftmailer不立即发送

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swiftmailer不立即发送相关的知识,希望对你有一定的参考价值。

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

只有在发送错误时才会发生这种情况。那是对的吗?

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

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

swiftmailer:

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

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

这个内核事件正在调用SymfonyBundleSwiftmailerBundleEventListenerEmailSenderListener::onTerminate()方法。您可以通过调度自己的事件并订阅上述方法来手动调用此方法。

src/App/Email/Events.php

<?php

namespace AppEmail;

class Events
{
    public const UNSPOOL = 'unspool';
}

config/services.yml

services:    
    AppEmailAmqpHandler:
      tags: [messenger.message_handler]

    SymfonyBundleSwiftmailerBundleEventListenerEmailSenderListener:
        tags:
            - name: kernel.event_listener
              event: !php/const AppEmailEvents::UNSPOOL
              method: onTerminate

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

<?php

namespace AppEmail;

use SymfonyComponentEventDispatcherEventDispatcherInterface;

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

另一答案

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

$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 }

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

另一答案

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

以上是关于Swiftmailer不立即发送的主要内容,如果未能解决你的问题,请参考以下文章

使用 swiftmailer 密件抄送多个地址

如何在 symfony 4 和 Swiftmailer 中测试发送电子邮件

为啥 swiftmailer 不采用环境变量?

使用 php、gmail 和 swiftmailer 发送电子邮件会导致与 SSL 相关的错误

不立即分离片段

Swiftmailer 的多个附件