通讯组件

5.2版本
保持 不明意

通讯组件

Messenger组件帮助应用程序向其他应用程序或通过消息队列发送和接收消息。

Matthias Noback系列的灵感来自于此关于命令总线的博客帖子SimpleBus项目

另请参阅

本文介绍如何在任何PHP应用程序中使用Messenger功能作为独立组件。阅读信使:同步和队列消息处理文章了解如何在Symfony应用程序中使用它。欧宝娱乐app下载地址

安装

1
美元作曲家需要symfony /信使欧宝娱乐app下载地址

请注意

如果在Symfony应用程序之外安装此组件,则必须使用欧宝娱乐app下载地址供应商/ autoload.php代码中的文件以启用Composer提供的类自动加载机制。读本文为更多的细节。

概念

发送方:
负责序列化和发送消息某物。例如,这可能是消息代理或第三方API。
接收者:
负责检索、反序列化和转发消息到处理器。例如,可以是消息队列提取器或API端点。
处理程序:
负责使用适用于消息的业务逻辑处理消息。处理程序被称为HandleMessageMiddleware中间件。
中间件:
中间件可以访问消息及其包装器(信封),同时通过总线发送。字面上地“中间的软件”,这些不是关于应用程序的核心关注点(业务逻辑)。相反,它们是适用于整个应用程序并影响整个消息总线的横切关注点。例如:日志记录、验证消息、启动事务……它们还负责调用链中的下一个中间件,这意味着它们可以通过向其添加戳记甚至替换它来调整信封,以及中断中间件链。中间件在最初分派消息时以及稍后从传输接收消息时都被调用。
信封:
Messenger特定概念,它在留言总线内提供完全灵活性,通过将消息包装到其中,允许在内部添加有用的信息信封邮票
信封上的邮票:
您需要附加到您的消息的信息:序列化器上下文用于传输,标识所接收的消息或中间件或传输层的任何类型元数据的标记可以使用。

公共汽车

总线用于派遣消息。总线的行为位于其有序的中间件堆栈中。该组件附带一组可以使用的中间件。

当使用Symfony的FrameworkBundle的消息总线时欧宝娱乐app下载地址,下面的中间件会为你配置:

  1. 欧宝娱乐app下载地址Symfony \中间件组件\信使\ \ SendMessageMiddleware(启用异步处理,如果传递记录器,请记录消息的处理)
  2. 欧宝娱乐app下载地址symfony \ component \ messenger \ middleware \ handlemessagemiddleware(调用注册处理程序)

例子:

应用\ \ MyMessage消息;应用MessageHandler \ \ MyMessageHandler;欧宝娱乐app下载地址Symfony \ HandlersLocator \信使\ \组件处理程序;欧宝娱乐app下载地址Symfony \ Component \ Messenger \ MessageBus;欧宝娱乐app下载地址symfony \ component \ messenger \ middleware \ handlemessagemiddleware;$处理程序=新的MyMessageHandler();$班车=新的MessageBus.([新的HandleMessageMiddleware(新的HandlersLocator([mymessage.::=>($处理程序],]),]);$班车- >调度(新的mymessage.(/ * ... * /));

请注意

每个中间件都需要实现欧宝娱乐app下载地址symfony \ component \ messenger \ middleware \ middlewareInterface

处理者

一旦派遣到总线,消息将由“消息处理程序”处理。消息处理程序是PHP可调用(即类的函数或类实例),这将对您的消息进行所需的处理:

命名空间app \ messageHandler.;应用\ \ MyMessage消息;MyMessageHandler{上市功能__invoke.(mymessage.$消息){/ /消息处理……}}

将元数据添加到消息(信封)

如果您需要向消息添加元数据或某些配置,请将其包装欧宝娱乐app下载地址symfony \ component \ messenger \信封分类并添加邮票。例如,要设置消息通过传输层时使用的序列化组,请使用serializerstamp.邮票:

欧宝娱乐app下载地址symfony \ component \ messenger \信封;欧宝娱乐app下载地址Symfony \组件\信使\ \ SerializerStamp邮票;$班车- >调度((新的信封($消息))- >(新的serializerstamp.([//组应用于整个消息,因此请确保//为每个嵌入对象定义组'团体'=>(“my_serialization_groups”],])));

以下是Symfony Messenger附带的一些重要信封邮票:欧宝娱乐app下载地址

  1. 欧宝娱乐app下载地址symfony \ component \ messenger \ stamp \ delaystamp,延迟处理异步消息。
  2. 欧宝娱乐app下载地址Symfony \组件\信使\ \ DispatchAfterCurrentBusStamp邮票,要使当前总线执行后处理消息。阅读更多事务性消息:在处理完成后处理新消息
  3. 欧宝娱乐app下载地址Symfony \组件\信使\ \ HandledStamp邮票,一个标记消息为特定处理程序所处理的戳记。允许访问处理程序返回值和处理程序名称。
  4. 欧宝娱乐app下载地址Symfony \ Component \ Messenger \ Stamp \ RecoveryStamp,一个标记从传输收到的消息的内部标记。
  5. 欧宝娱乐app下载地址symfony \ component \ messenger \ stamp \ sentstamp,一个标记特定发件人发送的消息的邮票。允许访问发件人FQCN和别名(如果可用)欧宝娱乐app下载地址symfony \ component \ messenger \ transport \ sender \ senderslocator
  6. 欧宝娱乐app下载地址Symfony \组件\信使\ \ SerializerStamp邮票,以配置传输所使用的序列化组。
  7. 欧宝娱乐app下载地址symfony \ component \ messenger \ stamp \ validationstamp,配置启用验证中间件时使用的验证组。

您接收到的是信封,而不是直接处理中间件中的消息。因此,您可以检查信封内容及其邮票,或添加任何:

应用程序消息\ \ \ AnotherStamp邮票;欧宝娱乐app下载地址symfony \ component \ messenger \信封;欧宝娱乐app下载地址symfony \ component \ messenger \ middleware \ middlewareInterface;欧宝娱乐app下载地址Symfony \中间件组件\信使\ \ StackInterface;欧宝娱乐app下载地址Symfony \ Component \ Messenger \ Stamp \ RecoveryStamp;MyOwnMiddleware实施midterwareInterface.{上市功能处理(信封美元的信封,堆栈接口$堆栈):信封{如果(空值!==美元的信封- >最后的(接受了::)){//信息刚刚收到…//例如,你可以添加另一个stamp。美元的信封=美元的信封- >(新的AnotherStamp(/ * ... * /));}其他的{//消息刚刚派出}返回$堆栈- >下一个()- >处理(美元的信封,$堆栈);}}

上面的示例将使用附加戳记将消息转发到下一个中间件如果刚刚收到了该消息(即至少有一个接受了邮票)。您可以通过实现创建自己的印章欧宝娱乐app下载地址Symfony \组件\信使\ \ StampInterface邮票

如果你想检查信封上的所有邮票,请使用$信封——> ()方法,它返回按类型(FQCN)分组的所有戳记。或者,您可以通过使用FQCN作为该方法的第一个参数来遍历特定类型的所有戳记。$信封 - >所有(接收洞::课程))。

请注意

如果通过使用运输,则必须使用Symfony Serializer组件进行序列化。欧宝娱乐app下载地址欧宝娱乐app下载地址Symfony \组件\信使\运输\序列化\序列化器基础串行器。

运输

要发送和接收消息,您必须配置传输。运输将负责与您的留言经纪人或第三方进行沟通。

你自己的发送者

想象一下,你已经拥有了一个重点通过消息总线进行消息并由处理程序处理。现在,您还希望将此消息发送为电子邮件(使用Mime梅勒组件)。

使用欧宝娱乐app下载地址Symfony \信使\交通\ \组件发送方\ SenderInterface,你可以创建自己的邮件发送人:

命名空间app \ messageender.;应用\ \ ImportantAction消息;欧宝娱乐app下载地址symfony \ component \ mailer \ mailerInterface;欧宝娱乐app下载地址symfony \ component \ messenger \信封;欧宝娱乐app下载地址Symfony \信使\交通\ \组件发送方\ SenderInterface;欧宝娱乐app下载地址symfony \ component \ mime \电子邮件;重要的是实施senderInterface.{私人$邮箱;私人toEmail美元;上市功能__construct(mailerInterface.$邮箱,细绳toEmail美元){$这一点- >邮箱=$邮箱;$这一点- >toEmail=toEmail美元;}上市功能发送(信封美元的信封):信封{$消息=美元的信封- >getMessage();如果(!$消息运算符重点){新的\ InvalidArgumentException.(sprintf(“此运输仅支持”%S“消息。,重点::));}$这一点- >邮箱- >发送((新的电子邮件())- >($这一点- >toEmail)- >主题(“重要行动”)- >HTML.(

重要行动

Made by '$消息- >getusername.()''));返回美元的信封;}}

你自己的接收者

接收器负责获取来自源的消息并将其分派给应用程序。

想象一下,您已经使用了应用程序中的一些“订单”里NewOrder消息。现在您希望与第三方或遗留应用程序集成,但您无法使用API​​,并且需要使用新订单的共享CSV文件。

您将阅读此CSV文件并调度里NewOrder消息。你需要做的就是编写自己的CSV接收器:

命名空间app \ messagereceiver.;app \ message \ neworder;欧宝娱乐app下载地址symfony \ component \ messenger \信封;欧宝娱乐app下载地址symfony \ component \ messenger \异常\ MessageCodingFailEdException;欧宝娱乐app下载地址Symfony \ Component \ Messenger \ Transport \ Receiver \ ReceptionInterface;欧宝娱乐app下载地址Symfony \ \序列化器\ SerializerInterface组件;empordersfromcsvfilereceiver实施接收接口{私人美元的序列化器;私人$ filepath.;上市功能__construct(SerializerInterface.美元的序列化器,细绳$ filepath.){$这一点- >序列化器=美元的序列化器;$这一点- >文件路径=$ filepath.;}上市功能得到():迭代{//根据您的运输接收信封(这里$ YourenVelope),//在大多数情况下,使用连接是最简单的解决方案。如果(空值= = =yourEnvelope美元){返回[];}尝试{美元的信封=$这一点- >序列化器- >解码(['身体'=>yourEnvelope美元('身体'],“标题”=>yourEnvelope美元(“标题”],]);}抓住(MessageCodingFailedException.$例外){$这一点- >联系- >拒绝(yourEnvelope美元(“id”]);$例外;}返回(美元的信封- >(新的Customstamp.(yourEnvelope美元(“id”]))];}上市功能(信封美元的信封):空白{//添加有关处理邮件的信息}上市功能拒绝(信封美元的信封):空白{//在自定义连接的情况下$这一点- >联系- >拒绝($这一点- >findCustomStamp(美元的信封)- >getid.());}}

接收方和发送方在同一总线上

为了允许在同一总线上发送和接收消息并防止无限循环,消息总线将添加一个欧宝娱乐app下载地址Symfony \ Component \ Messenger \ Stamp \ RecoveryStamp在信纸信封和欧宝娱乐app下载地址Symfony \中间件组件\信使\ \ SendMessageMiddleware中间件将知道不应该将这些消息再次路由到传输端。

这项工作包括代码样本,是在a下获得的许可创作共用BY-SA 3.0许可证。