如果有人通过消息队列(symfony/messenger)处理电子邮件,使用内存 spool 是首选。但是,内存 spool 只在 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
{
private $eventDispatcher;
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);
}
}
You can read about symfony/messenger here.
FOSUserBundle
发送电子邮件时,队列没有被刷新。我使用的是文件类型的 spool。因此,只有在我手动刷新时才会发送电子邮件。在我的旧机器上,这是自动完成的。 - Victor