Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Amqp Rpc Transporter Bundle Laravel Package

leberknecht/amqp-rpc-transporter-bundle

Symfony bundle that wires AMQP into your RPC transport layer, letting services send and receive remote procedure calls over RabbitMQ-style message queues with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony Messenger transport, not a Laravel package. There is no service provider, no config/queue.php driver, and no Illuminate\Queue integration. If you are working in a Laravel codebase, the first decision is whether you actually need this bundle or whether you should solve the problem with php-amqplib/enqueue directly inside Laravel. Use this bundle only if you are (a) in a Symfony app, or (b) deliberately booting a standalone Messenger bus inside a Laravel service provider.

Assuming a Symfony host app:

composer require leberknecht/amqp-rpc-transporter-bundle
pecl install amqp          # ext-amqp is required; this bundle is built on the C extension

Register the bundle in config/bundles.php (Symfony 4+):

return [
    // ...
    Leberknecht\AmqpRpcTransporterBundle\LeberknechtAmqpRpcTransporterBundle::class => ['all' => true],
];

Configure a transport in config/packages/messenger.yaml using whatever DSN scheme the bundle's TransportFactory::supports() registers (open that file first — the scheme is the single most important thing to confirm, likely amqp-rpc://):

framework:
    messenger:
        transports:
            rpc:
                dsn: '%env(RPC_DSN)%'
                options:
                    queue: rpc_requests
        routing:
            'App\Message\InventoryCheck': rpc

Where to look first, in order:

  1. The TransportFactory — confirms the DSN scheme and which options are parsed.
  2. The Transport class — check that it implements both TransportInterface (send) and ReceiverInterface (get). RPC over AMQP is fundamentally a two-way transport; if it only sends, it is not RPC.
  3. Search for correlation_id and reply_to — this is where the actual RPC semantics live.
  4. The bundle's README for the intended caller-side API (a blocking call() helper vs. manual envelope handling).

First use case: a synchronous request/response hop between two services over RabbitMQ where an HTTP call is unacceptable — e.g. an order service asking a pricing service for a quote and needing the answer in the same request lifecycle. That is the shape this bundle targets. If your use case is "dispatch and process later," use the stock amqp:// transport instead; this bundle buys you nothing.

Implementation Patterns

Caller side — treat RPC as a blocking dependency, isolate it behind a client class. Do not let Messenger envelopes leak into controllers.

final class PricingRpcClient
{
    public function __construct(private MessageBusInterface $bus) {}

    public function quote(QuoteRequest $request, int $timeoutMs = 2000): QuoteResponse
    {
        // Confirm the exact return contract of the transport in the package source:
        // some implementations return Envelope, some require a separate await() call.
        $envelope = $this->bus->dispatch($request);
        // ...unwrap QuoteResponse from $envelope here
    }
}

Wrap this in a decorator that adds a hard deadline, so a missing consumer fails fast instead of pinning a PHP-FPM worker:

public function quote(QuoteRequest $request, int $timeoutMs = 2000): QuoteResponse
{
    $start = microtime(true);
    try {
        return $this->inner->quote($request);
    } finally {
        if ((microtime(true) - $start) * 1000 > $timeoutMs) {
            // log slow RPC, emit a metric
        }
    }
}

Consumer side — run a dedicated worker for the RPC queue, not the shared one. RPC replies are latency-sensitive, and mixing them with batch jobs means your caller times out behind a long-running email job.

bin/console messenger:consume rpc --time-limit=3600 --memory-limit=128M

Contracts, not shared classes, across services. Define request/response DTOs in a small shared library with explicit serializer groups. Symfony's PhpSerializer is the default and is a trap for cross-language callers (a Node or Python service cannot read it). Force JSON:

framework:
    messenger:
        serializer:
            default_serializer: messenger.transport.symfony_serializer

Integration tips that actually matter day-to-day:

  • Prefer direct reply-to (amq.rabbitmq.reply-to) if the bundle supports it — no reply queue to declare, cleanly scoped to the channel. If it declares a named reply queue instead, ensure one queue per caller process or you get cross-talk.
  • Set a QoS/prefetch of 1 on the RPC consumer; concurrency here is a footgun, not an optimization.
  • Route by message class in messenger.yaml so RPC traffic never accidentally lands on the async transport. One misrouted class = silent hang.
  • Tag the RPC client as a service and inject an interface (RpcQuoteClient) so you can swap in a fake in tests. Never call the real RPC transport from a unit test.
  • For the Laravel bridge case: register everything as singletons in a service provider (TransportFactory, MessageBus, serializer) and expose a single RpcClient binding. Do not try to make Messenger's ConsumeMessagesCommand play nice with queue:work — run the Symfony command as a separate supervisor program.

Gotchas and Tips

  • Hard dependency on ext-amqp. Not installable on many shared/managed hosts, and the extension and the pure-PHP php-amqplib are not interoperable at the object level. Check php -m | grep amqp before you plan anything.
  • Symfony Messenger is fire-and-forget by design. The upstream send() contract has no notion of a return value. Any RPC transport has to bolt request/response on top, which means the caller must block. Audit the bundle's Transport for how it reconciles this — that's where the interesting (and most fragile) code is.
  • Correlation ID plumbing is the #1 failure mode. If requests and replies share a reply queue and correlation IDs are not strictly echoed, you will get responses delivered to the wrong caller under load. This typically surfaces only in production with concurrency > 1. Reproduce with two parallel callers before you trust it.
  • No consumer == hung request, not a failed request. Add a message TTL / x-message-ttl on the request queue and a client-side timeout, otherwise a missing pricing service takes down your checkout.
  • Serializer mismatch fails silently. Default PhpSerializer vs. JSON produces an empty or unhandled envelope that Messenger may just nack. Pin the serializer explicitly and write one integration test that round-trips a real DTO.
  • Deploys: messenger:stop-workers (or a Supervisor restart) is required; long-lived AMQP connections in workers will otherwise keep consuming stale code. Watch AMQP heartbeat settings on idle connections.
  • Maintenance signal is weak. Two stars, zero dependents, score 0.14. Read Transport.php and TransportFactory.php end-to-end before adopting — likely a few hundred lines, entirely auditable in 20 minutes. Pin the version in composer.json, and be prepared to vendor/fork it. It is more valuable as a reference implementation of direct reply-to in Messenger than as a long-term dependency.
  • Debugging toolkit: RabbitMQ management UI for reply_to/correlation_id inspection, rabbitmqctl list_queues name messages consumers, and a Messenger middleware that logs every dispatched envelope plus timing. If a call hangs, check consumers on the request queue first — it will be 0.
  • Extension points: decorate MessageBusInterface to add retries, circuit breaking, and metrics rather than patching the transport. If you need connection pooling or multi-broker failover, a custom TransportFactory delegating to the bundle's transport is cleaner than subclassing it.
  • Laravel reality check: if this is a pure Laravel app, the pragmatic answer is usually "no." Reach for vladimir-yuldashev/laravel-queue-rabbitmq for async, or php-amqplib with an explicit correlation_id/reply_to implementation for RPC — roughly 60 lines, fully under your control, and no Symfony Messenger coupling. This bundle earns its place only when a Symfony service is already on the other end of the wire.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource