sroze/messenger-enqueue-transport
An Enqueue transport for Symfony Messenger that routes messages through brokers such as AMQP, Redis, and other Enqueue-supported queues. It bridges Messenger’s transport layer with Enqueue for flexible, interoperable message queue backends.
This is a Symfony Messenger transport (enqueue://) that bridges Messenger to any php-enqueue broker — AMQP/RabbitMQ, Redis, SQS, STOMP, filesystem, etc. It is not a Laravel queue driver, so treat it as an interop tool: you use it when you need to consume/produce on a broker that another (usually Symfony) service already talks to, or when you deliberately want Messenger semantics inside Laravel.
Install the transport plus a concrete broker adapter (the adapter is not pulled in automatically):
composer require sroze/messenger-enqueue-transport enqueue/amqp-lib
# or: enqueue/redis, enqueue/sqs, enqueue/fs, enqueue/stomp
1.0.0 is the first stable tag and requires a modern Symfony (8 supported; EOL branches dropped) and PHP 8.4-friendly tooling. Verify your symfony/messenger constraint resolves before committing.
Configure the enqueue client — the transport DSN only references a named enqueue transport, it does not contain the broker credentials:
# config/packages/enqueue.yaml
enqueue:
default:
transport: 'amqp://guest:guest@rabbitmq:5672/%2f'
client: ~
Wire it as a Messenger transport, giving it a queue name via options:
# config/packages/messenger.yaml
framework:
messenger:
transports:
async:
dsn: 'enqueue://default'
options:
queue:
name: 'messages'
First use case: dispatch a message onto the transport, then consume it:
php bin/console messenger:consume async -vv
In a Laravel app you will not get this for free — there is no QUEUE_CONNECTION=enqueue. You need symfony/messenger installed, the framework's Messenger config loaded, and Messenger's console commands registered with the Laravel console kernel (or run the consumer as a separate Symfony/standalone process). Budget a small service provider for this.
Multiple transports, one broker connection. The enqueue://<name> DSN maps to an entry under enqueue: config, not to a queue. Reuse one named transport for many Messenger transports and vary only the queue option — this shares the underlying connection and keeps broker credentials out of Messenger config.
Routing by message class. The idiomatic split is a sync transport for latency-sensitive commands and an enqueue:// transport for everything async:
framework:
messenger:
routing:
'App\Message\SendInvoice': async
'App\Message\ReindexProduct': async
Retries and failures belong to Messenger, not the broker. Configure retry_strategy and a failure_transport on the Messenger transport. Let the broker keep its own dead-lettering off unless you have an operational reason — otherwise you get two competing retry mechanisms and duplicated processing.
Worker lifecycle. Run consumers under Supervisor/systemd with bounded --time-limit and --memory-limit, and restart on deploy (messenger:stop-workers). This mirrors queue:work discipline but uses Messenger's flags. Long-running enqueue consumers are the classic place to leak memory, especially with large payloads.
Serializer interop is the real design decision. Symfony's default PhpSerializer puts a PHP-serialized object on the wire. That is fine for PHP-only, same-codebase pairs, but a non-Symfony consumer (Node, Go, a Laravel queue worker) cannot read it. For cross-stack messaging use Messenger's Serializer with a Symfony Serializer configured for JSON, and accept that the envelope shape (body, headers) is Messenger's, not a plain JSON payload. If the other side is fixed and expects a bare JSON body, write a small custom transport/serializer rather than fighting the default.
Consumer-side integration in Laravel. The pragmatic pattern is a thin artisan command or a queued job that pulls from Messenger's MessageBusInterface::dispatch() for producing, and a standalone process for consuming. Keep the Messenger RoutableMessageBus/handlers in a app/Messenger/ namespace registered via a service provider.
Testing. Swap the transport for in-memory:// or sync:// in the test environment; never point the suite at a real broker. For transport-level tests, enqueue ships an in-memory/fs adapter that is easier to assert against than RabbitMQ.
Extension points. EnqueueTransportFactory is the seam: decorate it (or the resulting EnqueueTransport) to add headers, tracing IDs, or metrics without touching the vendor code. Likewise, configure the enqueue client with your own Context/ConnectionFactory if you need custom broker options (TLS, heartbeats, prefetch).
QUEUE_CONNECTION. Laravel's dispatch(), ShouldQueue, and queue:work are wired to Laravel's queue manager. This package has no Laravel driver, no facade, no config stub. If what you actually want is RabbitMQ behind Laravel jobs, use vyuldashev/laravel-queue-rabbitmq instead; reach for this package only when Messenger compatibility is the point.composer update. Check composer why-not sroze/messenger-enqueue-transport 1.0.0 before assuming a code problem.php-cs-fixer nullable-config bump is a dev-tooling fix, no runtime behavior change — don't chase it in a changelog diff.Transport not found / null context. Almost always a name mismatch between the DSN (enqueue://default) and the key under enqueue: config, or the enqueue bundle not being loaded at all in your hand-rolled Laravel bootstrap.options.queue.name — not options.queue_name. Flags (durable, auto-delete, max-priority, arguments) go in the same queue array and are broker-specific; wrong flags silently create a different queue than the one your other service declared, and messages vanish into it.messenger:consume async -vv for the consumer side, the enqueue Context for broker-side errors, then the broker UI (RabbitMQ management, redis-cli MONITOR). Broker-side queue depth is the truth; Messenger's messenger:failed:show only covers what it captured.How can I help you explore Laravel packages today?