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

Laravel Websockets Laravel Package

beyondcode/laravel-websockets

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require beyondcode/laravel-websockets
    php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
    php artisan migrate
    
  2. Configure .env:

    BROADCAST_DRIVER=pusher
    PUSHER_APP_ID=1
    PUSHER_APP_KEY=your-app-key
    PUSHER_APP_SECRET=your-app-secret
    PUSHER_APP_CLUSTER=mt1
    MIX_PUSHER_APP_CLUSTER=mt1
    
  3. Run the server:

    php artisan websockets:serve
    

    (For production, use php artisan websockets:serve --daemon or a process manager like Supervisor.)

  4. First Use Case:

    • Use Laravel Echo in your frontend (e.g., Vue/React) to subscribe to channels:
      import Echo from 'laravel-echo';
      window.Pusher = require('pusher-js');
      window.Echo = new Echo({
          broadcaster: 'pusher',
          key: process.env.MIX_PUSHER_APP_KEY,
          wsHost: window.location.hostname,
          wsPort: 6001,
          forceTLS: false, // Set to `true` in production
          disableStats: true,
      });
      
    • Broadcast an event from Laravel:
      use App\Events\MessageSent;
      broadcast(new MessageSent('Hello, WebSockets!'))->toOthers();
      

Implementation Patterns

Core Workflows

  1. Channel-Based Communication:

    • Use Laravel’s built-in channels (e.g., private-user.{id}, presence-channel.{name}) with Echo.
    • Example: Private messaging with presence tracking:
      Echo.join(`private-user.${userId}`)
           .here((users) => console.log('Users here:', users))
           .joining((user) => console.log('User joined:', user))
           .leaving((user) => console.log('User left:', user));
      
  2. Event Broadcasting:

    • Extend Laravel’s Event class and use broadcast():
      class MessageSent implements ShouldBroadcast
      {
          public $message;
          public function __construct($message) { $this->message = $message; }
          public function broadcastOn() { return new PrivateChannel('user.' . auth()->id()); }
      }
      
  3. Debugging with Dashboard:

    • Access http://your-app.test:6001 (or production URL) to monitor:
      • Connected clients.
      • Broadcasted events.
      • Channel subscriptions.
  4. Scaling:

    • Horizontal Scaling: Run multiple instances of websockets:serve behind a load balancer (e.g., Nginx).
    • Redis Backend: Configure BROADCAST_CONNECTION=redis in .env for distributed broadcasting.
  5. Authentication:

    • Use Laravel’s BroadcastAuthorization trait to restrict access:
      class PrivateChannel extends Channel
      {
          public function join($connector, $channel, $request)
          {
              return (int) $request->user()->id === (int) $channel;
          }
      }
      

Integration Tips

  • Frontend: Ensure CORS is configured in config/websockets.php:
    'allowed_origins' => ['http://localhost:3000', 'https://your-app.com'],
    
  • Testing: Use php artisan websockets:test to simulate connections in CI.
  • SSL: Enable in production via forceTLS: true in Echo and configure SSL in config/websockets.php:
    'ssl' => [
        'local_cert' => '/path/to/cert.pem',
        'local_pk'   => '/path/to/private.key',
        'passphrase' => 'your-passphrase',
    ],
    

Gotchas and Tips

Pitfalls

  1. Port Conflicts:

    • Default port is 6001. Ensure it’s free or change it in .env:
      WEBSOCKETS_PORT=6002
      
    • Debug with netstat -tulnp | grep 6001 (Linux/Mac).
  2. Redis vs. Database:

    • Database driver: Works locally but fails in distributed setups. Use Redis for production:
      BROADCAST_CONNECTION=redis
      QUEUE_CONNECTION=redis
      
  3. Echo Configuration Mismatch:

    • Ensure wsHost in Echo matches your WebSocket server’s domain/IP.
    • For local development, use wsHost: window.location.hostname; for production, use the public URL (e.g., wss://your-app.com).
  4. Daemon Mode Quirks:

    • Logs are written to storage/logs/websockets.log. Tail the log for errors:
      tail -f storage/logs/websockets.log
      
    • Use --daemon carefully; processes may not restart automatically on crashes.
  5. Channel Naming:

    • Avoid dynamic channel names in loops (e.g., private-user.{$id}). Use PrivateChannel with authorization instead.

Debugging

  • Connection Issues:
    • Check browser console for WebSocket errors (e.g., WebSocket connection to 'ws://...' failed).
    • Verify allowed_origins in config/websockets.php includes your frontend URL.
  • Broadcast Failures:
    • Ensure the event implements ShouldBroadcast and broadcastOn() returns a valid channel.
    • Check storage/logs/laravel.log for broadcasting errors.

Extension Points

  1. Custom Middleware:

    • Add middleware to filter connections:
      // config/websockets.php
      'middleware' => [
          \BeyondCode\LaravelWebSockets\Middleware\Authorize::class,
          \App\Middleware\CustomMiddleware::class,
      ];
      
    • Example middleware:
      class CustomMiddleware
      {
          public function handle($request, \Closure $next)
          {
              if (!$request->query->has('auth_token')) {
                  return false;
              }
              return $next($request);
          }
      }
      
  2. Event Filtering:

    • Use broadcast()->toOthers() or broadcast()->only() to target specific clients:
      broadcast(new MessageSent('Hi'))->toOthers(); // Exclude sender
      broadcast(new MessageSent('Hi'))->only([1, 2, 3]); // Target specific user IDs
      
  3. Metrics and Monitoring:

    • Integrate with Prometheus or custom logging:
      // config/websockets.php
      'metrics' => [
          'enabled' => true,
          'port' => 9090,
      ],
      
    • Expose metrics at http://your-app.test:9090/metrics.
  4. Proxy Setup:

    • Use Nginx to proxy WebSocket traffic:
      location /ws {
          proxy_pass http://localhost:6001;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          proxy_set_header Host $host;
      }
      
    • Update Echo’s wsHost to /ws if using a subpath.

Configuration Quirks

  • Environment Variables:
    • PUSHER_APP_KEY must match the key used in Echo (even though it’s not used for auth).
    • WEBSOCKETS_PORT defaults to 6001; override in .env if needed.
  • Debug Dashboard:
    • Accessible at http://{host}:{port} (e.g., http://localhost:6001).
    • Requires debug mode in config/websockets.php:
      'debug' => env('APP_ENV') !== 'production',
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware