通过 Symfony Messenger 执行邮件发送
Executing mail sending via Symfony Messenger
我正在寻找对我的代码有很大帮助的人。
我尽我所能连接一些 Symfony 功能,我想我要去某个地方..
我正在使用 Symfony 4.2 和 API 平台并尝试添加异步使用电子邮件消息发送的过程。
我有我的 Comment 实体,它在持久实体上触发它。它触发了我的 __invoke 函数,但出现了问题。我不太明白下一步该怎么做。
正如文档 here 中所述,首先我需要配置 Data Persister:
<?php
namespace App\DataPersister;
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Entity\Comment;
final class EmailNotificationDataPersister implements ContextAwareDataPersisterInterface
{
private $decorated;
private $mailer;
public function __construct(ContextAwareDataPersisterInterface $decorated, \Swift_Mailer $mailer)
{
$this->decorated = $decorated;
$this->mailer = $mailer;
}
public function supports($data, array $context = []): bool
{
return $this->decorated->supports($data, $context);
}
public function persist($data, array $context = [])
{
$result = $this->decorated->persist($data, $context);
if (
$data instanceof Comment && (
($context['collection_operation_name'] ?? null) === 'post')
) {
$this->sendWelcomeEmail($data);
}
return $result;
}
public function remove($data, array $context = [])
{
return $this->decorated->remove($data, $context);
}
private function sendWelcomeEmail(Comment $comment)
{
// Your welcome email logic...
// $this->mailer->send(...);
}
}
我使用的是 Symfony 4.2,所以我安装了 swift 邮件客户端。
我还定义了 EmailSubscriber:
<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Comment;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\Messenger\MessageBusInterface;
final class EmailNotificationSubscriber implements EventSubscriberInterface
{
private $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => [ 'sendMail', EventPriorities::POST_WRITE],
];
}
public function sendMail(GetResponseForControllerResultEvent $event)
{
$comment = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$comment instanceof Comment || Request::METHOD_POST !== $method) {
return;
}
$this->messageBus->dispatch(new Comment());
}
}
最后我实现了处理程序:
<?php
namespace App\Handler;
use App\Entity\Comment;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
final class EmailNotificationHandler implements MessageHandlerInterface
{
public function __invoke(Comment $comment)
{
// do something with the resource
}
}
当我在我的 api 平台中触发持久化实体时,调用函数中的 var_dump() 被捕获。
我不知道是不是出了什么问题,接下来我该怎么做。 我需要使用 Symfony Messenger 异步执行电子邮件发送。
在我的 .env 文件中:
MESSENGER_TRANSPORT_DSN=amqp://127.0.0.1:8000/api/messages
和框架.yaml
messenger:
transports:
amqp: "%env(MESSENGER_TRANSPORT_DSN)%"
routing:
'App\Entity\Comment': amqp
还有什么方法可以向用户 table 中发布的任意随机邮件发送电子邮件?我想为此设置邮件程序配置。
对于 运行 异步操作,您需要 transport。对于本地测试 symfony 服务器和 docker 效果很好。
#config/packages/messenger.yaml
transports:
async: '%env(RABBITMQ_DSN)%'
将 docker-compose.yaml
放在项目根目录。
rabbitmq:
image: rabbitmq:3-management
ports: [5672, 15672]
运行 在控制台中
docker-compose up -d
symfony server:start -d
用于在控制台
中使用消息运行
symfony console messenger:consume async -vv
在生产环境中,您必须为 RabbitMQ、Amazon SQS 等添加 RABBITMQ_DSN
(或 MESSENGER_TRANSPORT_DSN
),并可能使用 Supervisor 来使用消息。
我正在寻找对我的代码有很大帮助的人。 我尽我所能连接一些 Symfony 功能,我想我要去某个地方..
我正在使用 Symfony 4.2 和 API 平台并尝试添加异步使用电子邮件消息发送的过程。
我有我的 Comment 实体,它在持久实体上触发它。它触发了我的 __invoke 函数,但出现了问题。我不太明白下一步该怎么做。
正如文档 here 中所述,首先我需要配置 Data Persister:
<?php
namespace App\DataPersister;
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Entity\Comment;
final class EmailNotificationDataPersister implements ContextAwareDataPersisterInterface
{
private $decorated;
private $mailer;
public function __construct(ContextAwareDataPersisterInterface $decorated, \Swift_Mailer $mailer)
{
$this->decorated = $decorated;
$this->mailer = $mailer;
}
public function supports($data, array $context = []): bool
{
return $this->decorated->supports($data, $context);
}
public function persist($data, array $context = [])
{
$result = $this->decorated->persist($data, $context);
if (
$data instanceof Comment && (
($context['collection_operation_name'] ?? null) === 'post')
) {
$this->sendWelcomeEmail($data);
}
return $result;
}
public function remove($data, array $context = [])
{
return $this->decorated->remove($data, $context);
}
private function sendWelcomeEmail(Comment $comment)
{
// Your welcome email logic...
// $this->mailer->send(...);
}
}
我使用的是 Symfony 4.2,所以我安装了 swift 邮件客户端。
我还定义了 EmailSubscriber:
<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Comment;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\Messenger\MessageBusInterface;
final class EmailNotificationSubscriber implements EventSubscriberInterface
{
private $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => [ 'sendMail', EventPriorities::POST_WRITE],
];
}
public function sendMail(GetResponseForControllerResultEvent $event)
{
$comment = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$comment instanceof Comment || Request::METHOD_POST !== $method) {
return;
}
$this->messageBus->dispatch(new Comment());
}
}
最后我实现了处理程序:
<?php
namespace App\Handler;
use App\Entity\Comment;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
final class EmailNotificationHandler implements MessageHandlerInterface
{
public function __invoke(Comment $comment)
{
// do something with the resource
}
}
当我在我的 api 平台中触发持久化实体时,调用函数中的 var_dump() 被捕获。
我不知道是不是出了什么问题,接下来我该怎么做。 我需要使用 Symfony Messenger 异步执行电子邮件发送。
在我的 .env 文件中:
MESSENGER_TRANSPORT_DSN=amqp://127.0.0.1:8000/api/messages
和框架.yaml
messenger:
transports:
amqp: "%env(MESSENGER_TRANSPORT_DSN)%"
routing:
'App\Entity\Comment': amqp
还有什么方法可以向用户 table 中发布的任意随机邮件发送电子邮件?我想为此设置邮件程序配置。
对于 运行 异步操作,您需要 transport。对于本地测试 symfony 服务器和 docker 效果很好。
#config/packages/messenger.yaml
transports:
async: '%env(RABBITMQ_DSN)%'
将 docker-compose.yaml
放在项目根目录。
rabbitmq:
image: rabbitmq:3-management
ports: [5672, 15672]
运行 在控制台中
docker-compose up -d
symfony server:start -d
用于在控制台
中使用消息运行symfony console messenger:consume async -vv
在生产环境中,您必须为 RabbitMQ、Amazon SQS 等添加 RABBITMQ_DSN
(或 MESSENGER_TRANSPORT_DSN
),并可能使用 Supervisor 来使用消息。