danieldkorytek/messenger-bridge-bundle

Docplanner 消息标准的消息桥

安装量: 17,655

依赖项: 0

建议者: 0

安全: 0

星标: 1

关注者: 3

分支: 1

开放问题: 0

类型:symfony-bundle

0.6.1 2022-01-17 18:05 UTC

This package is auto-updated.

Last update: 2024-09-18 00:00:41 UTC


README

路由键中间件

该中间件提供了修改路由键的能力,例如:将当前区域键添加到当前消息键中。

RoutingKeyMiddleware 实现 RoutingKeyResolverInterface

配置

  • 注册中间件
messenger.bridge.routing.app_id_routing_key_resolver:
   class: DanielKorytek\MessengerBridgeBundle\Message\Routing\RoutingKeyResolver\AppIdRoutingKeyResolver

Symfony < 5.1
messenger.bridge.middleware.routing_key:
   class: DanielKorytek\MessengerBridgeBundle\Middleware\RoutingKeyMiddleware
   arguments:
     - '@messenger.bridge.routing.app_id_routing_key_resolver'
   tags:
     - { name: messenger.middleware }

Symfony >= 5.1

messenger.bridge.middleware.routing_key:
   class: DanielKorytek\MessengerBridgeBundle\Middleware\Symf51\RoutingKeyMiddleware
   arguments:
     - '@messenger.bridge.routing.app_id_routing_key_resolver'
   tags:
     - { name: messenger.middleware }
  • 将中间件附加到 messenger

messenger.yml 中将 messenger.bridge.middleware.routing_key 添加到您的总线中间件列表。

示例

framework:
       messenger:
           default_bus: command.bus
           buses:
               command.bus: ~
               shared.message.bus:
                   default_middleware: allow_no_handlers
                   middleware:
                       - messenger.bridge.middleware.routing_key

序列化

对于序列化和反序列化消息,该包使用 symfony/serializer。为了确保序列化和反序列化过程的充分可能性,您需要启用标准化和反标准化。

必需的序列化器配置

services:
    serializer.property.normalizer:
        class: Symfony\Component\Serializer\Normalizer\PropertyNormalizer
        arguments:
            - '@serializer.mapping.class_metadata_factory'
            - '@serializer.name_converter.metadata_aware'
            - '@property_info'
            - '@serializer.mapping.class_discriminator_resolver'
            - null
            - []
        tags:
            - { name: serializer.normalizer }

    serializer.date_time.normalizer:
        class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer
        tags:
            - { name: serializer.normalizer }

    serializer.array_denormalizer:
        class: Symfony\Component\Serializer\Normalizer\ArrayDenormalizer
        tags:
            - { name: serializer.denormalizer }

总线示例配置

framework:
    messenger:
        #your other buses here
        buses:
            shared.message.bus:
                default_middleware: allow_no_handlers
                middleware:
                    #here other middlewares like doctorine transaction etc.
                    - messenger.bridge.middleware.routing_key
        #here is global bus serializer configuration
        serializer:
            default_serializer: messenger.transport.symfony_serializer
            symfony_serializer:
                format: json
                context: { }
        #here is transport configuration
        transports:
            #other transports here
            shared: #configuration of outgoing exchange (messenger is publishing messages here to other apps)
                serializer: messenger.bridge.serializer #our custom serializer for correct serialization/deserialization shared event messages 
                dsn: "%env(MESSENGER_TRANSPORT_DSN)%" #dsn to rabbitmq
                options:
                    exchange:
                    name: "%env(MESSENGER_SHARED_EXCHANGE_NAME)%" #outgoing exchange name 
                    type: topic
            
            incoming:
                 serializer: messenger.bridge.serializer
                 dsn: "%env(MESSENGER_TRANSPORT_DSN)%"
                 options:
                    queues:
                        incoming_events: #your queue name (here yours app receives messages from other apps via exchange)
                            binding_keys:
                                - "%locale%.app-name.smth.changed" #routing key binding list
                    exchange:
                        name: "%env(MESSENGER_SHARED_INCOMING_EXCHANGE_NAME)%" #incoming exchange name
                        type: topic

消息

所有消息表示类 必须实现 NamedMessageInterface。每个由总线处理的、没有实现 NamedMessageInterface 的消息将抛出 UnsupportedMessage 异常。

发布

  1. 检查您的总线是否具有 allow_no_handlers 中间件(这是必需的)。您的总线只有在没有为该消息提供订阅者类时,才会将消息发布到传输。
  2. 将您的消息 FQCN 添加到 messenger 路由配置,并使用正确的传输名称
       routing:
                'App\SharedEventBus\Test': shared
    

订阅

  • 为外部消息注册序列化器
services:

  messenger.bridge.bus_stamp_docplanner.serializer:
    class: DanielKorytek\MessengerBridgeBundle\Message\Serializer\BusStampEnvelopeSerializer
    arguments:
      - '@messenger.bridge.serializer' #docplanner SEB  messages serializer
      - 'shared.message.bus' #bus name from messenger configuration
  • 在您的传入传输中添加消息绑定键:这一步是为 messenger 命令。如果您使用不同的包,您应该在适当的位置更新配置。
 incoming:
    serializer: messenger.bridge.bus_stamp_docplanner.serializer 
    dsn: "%env(MESSENGER_TRANSPORT_DSN)%"
    options:
        queues:
            incoming_events: #your queue name (here yours app receives messages from other apps via exchange)
                binding_keys:
                    - "%locale%.app-name.smth.changed"
                    - "%locale%.app-name.smth"  #new key
        exchange:
            name: "%env(MESSENGER_SHARED_INCOMING_EXCHANGE_NAME)%" #incoming exchange name
            type: topic
service:
   messenger.bridge.bus_stamp_docplanner.serializer:
        class: DanielKorytek\MessengerBridgeBundle\Message\Serializer\BusStampEnvelopeSerializer
        arguments:
            - '@messenger.bridge.serializer'
            - 'bus.name.from.messenger.configuration'
  • 为消息创建表示类。
  • 将消息映射附加到 messenger.bridge.subscriber_events_mapping 参数
messenger.bridge.subscriber_events_mapping:
    app-name.smth.changed: App\Namespace\MessageClass
  • 创建订阅者类并将其绑定到正确的总线
<?php

declare(strict_types=1);

namespace App\SharedEventBus;


use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;

class SaasAttendanceSubscriber implements MessageSubscriberInterface
{
    public function __invoke(MessageClass $messageClass): Envelope
    {
        return new Envelope($messageClass);
    }

    public static function getHandledMessages(): iterable
    {
        yield MessageClass::class => [
            'bus' => 'shared.message.bus',
        ];
    }

}