Weave Code
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

Messenger Laravel Package

symfony/messenger

Symfony Messenger helps PHP apps send and receive messages via async transports and message queues. Dispatch commands/events, route to handlers, and integrate with workers and transports to decouple services and improve scalability.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/messenger
    

    For Laravel, use symfony/messenger alongside symfony/amqp-messenger (for AMQP) or symfony/doctrine-messenger (for Doctrine transport).

  2. Define a Message Class:

    namespace App\Messages;
    
    class SendEmailMessage
    {
        public function __construct(public string $email, public string $subject) {}
    }
    
  3. Create a Message Handler:

    namespace App\MessageHandlers;
    
    use App\Messages\SendEmailMessage;
    use Symfony\Component\Messenger\Attribute\AsMessageHandler;
    
    #[AsMessageHandler]
    class SendEmailHandler
    {
        public function __invoke(SendEmailMessage $message)
        {
            // Logic to send email
        }
    }
    
  4. Dispatch a Message:

    use Symfony\Component\Messenger\MessageBusInterface;
    
    public function __construct(private MessageBusInterface $bus) {}
    
    public function sendWelcomeEmail(string $email)
    {
        $this->bus->dispatch(new SendEmailMessage($email, 'Welcome!'));
    }
    
  5. Consume Messages (CLI):

    php bin/console messenger:consume async -vv
    

First Use Case

Use Messenger to asynchronously send emails or process background jobs (e.g., image resizing, report generation) without blocking HTTP responses.


Implementation Patterns

Core Workflows

1. Synchronous vs. Asynchronous Dispatch

  • Synchronous: Dispatch and wait for completion (default).
    $this->bus->dispatch($message);
    
  • Asynchronous: Use AsyncBus (requires transport like Redis, AMQP, or Doctrine).
    $this->bus->dispatch($message); // Handled by transport
    

2. Transport Configuration

Configure transports in config/packages/messenger.yaml:

framework:
    messenger:
        transports:
            async: '%env(MESSENGER_TRANSPORT_DSN)%' # e.g., 'doctrine://default'
            failed: 'doctrine://default' # For failed messages
        routing:
            'App\Messages\SendEmailMessage': async

3. Handling Failures

  • Retry Mechanism: Use RetryStamp or configure retry delays.
    use Symfony\Component\Messenger\Stamp\RetryStamp;
    
    $message->with(new RetryStamp(3)); // Retry 3 times
    
  • Failed Messages: Consume from the failed transport:
    php bin/console messenger:consume failed -vv
    

4. Delayed Messages

Use DelayStamp for scheduled execution:

use Symfony\Component\Messenger\Stamp\DelayStamp;

$message->with(new DelayStamp(3600)); // Delay 1 hour

5. Batching Messages

Group messages for efficiency (e.g., bulk emails):

# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            async:
                dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
                options:
                    batch_size: 50 # Process 50 messages at once

6. Middleware Integration

Add middleware to modify messages (e.g., logging, validation):

use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;

class LoggingMiddleware implements MiddlewareInterface
{
    public function handle($message, StackInterface $next)
    {
        \Log::info('Handling message', ['message' => $message]);
        return $next($message);
    }
}

Register in config/packages/messenger.yaml:

framework:
    messenger:
        middleware:
            - App\Middleware\LoggingMiddleware

7. Signing Messages (Security)

Prevent tampering with SignatureStamp:

use Symfony\Component\Messenger\Stamp\SignatureStamp;

$message->with(new SignatureStamp('my_secret_key'));

Configure in messenger.yaml:

framework:
    messenger:
        signature_keys: ['my_secret_key']

8. Testing Messages

Use TestMessageBus for unit tests:

use Symfony\Component\Messenger\Test\MessageBus;

$bus = new MessageBus([new TestMessageBus()]);
$bus->dispatch($message);
$enqueuedMessages = $bus->getEnqueuedMessages();

Laravel-Specific Patterns

1. Service Provider Setup

Register Messenger in AppServiceProvider:

use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;

public function boot()
{
    $this->app->bind(MessageBus::class, function ($app) {
        return new MessageBus([
            new HandleMessageMiddleware($app->get('messenger.message_bus_provider')),
        ]);
    });
}

2. Queue Workers

Use Laravel’s queue system alongside Messenger:

php artisan queue:work --queue=async

Configure in config/queue.php:

'connections' => [
    'async' => [
        'driver' => 'messenger',
        'dsn' => env('MESSENGER_TRANSPORT_DSN'),
    ],
],

3. Event-Driven Workflows

Combine Messenger with Laravel Events:

use Symfony\Component\Messenger\MessageBusInterface;

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

    public function handle(UserRegistered $event)
    {
        $this->bus->dispatch(new SendWelcomeEmailMessage($event->user->email));
    }
}

4. Command Bus for CLI

Use Messenger for CLI commands:

use Symfony\Component\Messenger\Attribute\AsCommand;

#[AsCommand]
class ProcessOrdersCommand
{
    public function __invoke()
    {
        // Process orders asynchronously
    }
}

Run with:

php bin/console messenger:consume commands -vv

Gotchas and Tips

Pitfalls

1. Transport-Specific Issues

  • Doctrine Transport: Ensure your database schema is up-to-date. Run:
    php bin/console messenger:setup-transport doctrine://default
    
  • Redis Transport: Avoid memory leaks with large batches. Monitor Redis memory usage.
  • AMQP Transport: Configure heartbeat and reconnect_delay to handle network issues:
    options:
        heartbeat: 300
        reconnect_delay: 500
    

2. Message Serialization

  • Custom objects must implement Serializable or use __toString() for serialization.
  • Avoid circular references in messages (e.g., User referencing Order which references User).

3. Handler Autowiring

  • Ensure handlers are public and invokable (no constructor arguments unless bound in DI container).
  • Use #[AsMessageHandler] (PHP 8+) or @AsMessageHandler (PHP 7.4) for clarity.

4. Failed Message Handling

  • Failed messages are not automatically retried unless configured. Use RetryStamp or a RetryMiddleware.
  • Clear the failed transport manually if needed:
    php bin/console messenger:failed:remove --all
    

5. Performance Bottlenecks

  • Batch Size: Too large batches can cause timeouts. Start with batch_size: 20-50.
  • Worker Concurrency: Limit concurrent workers to avoid resource exhaustion:
    php bin/console messenger:consume async -vv --limit=10
    

6. Debugging

  • Enable debug mode for verbose output:
    php bin/console messenger:consume async -vvv
    
  • Use Xdebug with messenger:debug:
    php bin/console messenger:debug
    

Tips

1. Configuration Best Practices

  • Environment Variables: Store transport DSNs in .env:
    MESSENGER_TRANSPORT_DSN=doctrine://default
    
  • Transport Fallbacks: Define fallback transports for high availability:
    transports:
        async:
            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
            fallback: 'sync://'
    

2. Monitoring

  • Track message throughput with messenger:stats:
    php bin/console messenger
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport