【发布时间】:2022-01-21 17:19:34
【问题描述】:
编辑:这个问题是在尝试在同一个应用程序中同时拥有同步和同步电子邮件时出现的。没有说清楚。在撰写本文时,这是不可能的,至少不像这里尝试的那样简单。请参阅下面@msg 的 cmets。
配置为异步发送电子邮件而不是立即发送电子邮件的电子邮件服务。这发生在doctrine 或amqp 被选为MESSENGER_TRANSPORT_DSN 时。 doctrine 传输成功创建 messenger_messages 表,但没有内容。这告诉我观察到MESSENGER_TRANSPORT_DSN。使用 RabbitMQ 'Hello World' 教程对 amqp 的简单测试表明它已正确配置。
我在下面的代码中遗漏了什么?
如下所示的序列摘要:添加机会 -> OppEmailService 创建电子邮件内容 -> 从 EmailerService 获取 TemplatedEmail() 对象(未显示) -> 将 TemplatedEmail() 对象提交给 LaterEmailService,配置为异步。
messenger.yaml:
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
sync: 'sync://'
routing:
'App\Services\NowEmailService': sync
'App\Services\LaterEmailService': async
OpportunityController:
class OpportunityController extends AbstractController
{
private $newOpp;
private $templateSvc;
public function __construct(OppEmailService $newOpp, TemplateService $templateSvc)
{
$this->newOpp = $newOpp;
$this->templateSvc = $templateSvc;
}
...
public function addOpp(Request $request): Response
{
...
if ($form->isSubmitted() && $form->isValid()) {
...
$volunteers = $em->getRepository(Person::class)->opportunityEmails($opportunity);
$this->newOpp->oppEmail($volunteers, $opportunity);
...
}
OppEmailService:
class OppEmailService
{
private $em;
private $makeMail;
private $laterMail;
public function __construct(
EmailerService $makeMail,
EntityManagerInterface $em,
LaterEmailService $laterMail
)
{
$this->makeMail = $makeMail;
$this->em = $em;
$this->laterMail = $laterMail;
}
...
public function oppEmail($volunteers, $opp): array
{
...
$mailParams = [
'template' => 'Email/volunteer_opportunities.html.twig',
'context' => ['fname' => $person->getFname(), 'opportunity' => $opp,],
'recipient' => $person->getEmail(),
'subject' => 'New volunteer opportunity',
];
$toBeSent = $this->makeMail->assembleEmail($mailParams);
$this->laterMail->send($toBeSent);
...
}
}
LaterEmailService:
namespace App\Services;
use Symfony\Component\Mailer\MailerInterface;
class LaterEmailService
{
private $mailer;
public function __construct(MailerInterface $mailer)
{
$this->mailer = $mailer;
}
public function send($email)
{
$this->mailer->send($email);
}
}
【问题讨论】:
-
在 messenger.yaml 中的“路由”下,您应该将消息类映射到传输,而不是像您所做的那样将服务映射到传输。
-
我对 Message 类的理解是它期望
$context是一个字符串。 See this。在symfonycasts 他们只将所有电子邮件显示为异步 -
消息类是一种 Dto,它保存消息处理程序所需要的数据。它可以包含任何数据,而不是必需的字符串。当推送到消息总线时,消息无论如何都会被序列化。整个过程应该是这样的:你创建一个消息,将它推送到一个消息总线(MessageBusInterface)。收到消息后,处理程序会对其进行处理。
-
我在您的代码中看不到将消息推送到 MessageBusInterface::dispatch 的部分。在 OpportunityController 中,您调用 OppEmailService,后者又调用 LaterEmailService,后者发送电子邮件。这里不涉及 Symfony Messager。
-
如前所述,您的
framework.messenger.routing配置错误。您应该映射消息类,而不是服务。
标签: php symfony symfony-messenger