danieldkorytek / messenger-bridge-bundle
Docplanner 消息标准的消息桥
0.6.1
2022-01-17 18:05 UTC
Requires
- php: ^7.2.5 || ^8.0
- symfony/dependency-injection: *
- symfony/http-kernel: *
- symfony/messenger: ^4.4 || ^5.0 || ^6.0
- symfony/serializer: *
Suggests
- symfony/amqp-messenger: Required since symfony/messenger:^5.1
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
异常。
发布
- 检查您的总线是否具有
allow_no_handlers
中间件(这是必需的)。您的总线只有在没有为该消息提供订阅者类时,才会将消息发布到传输。 - 将您的消息 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', ]; } }