Installation:
composer require beyondcode/laravel-websockets
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan migrate
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
Run the server:
php artisan websockets:serve
(For production, use php artisan websockets:serve --daemon or a process manager like Supervisor.)
First Use Case:
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,
});
use App\Events\MessageSent;
broadcast(new MessageSent('Hello, WebSockets!'))->toOthers();
Channel-Based Communication:
private-user.{id}, presence-channel.{name}) with Echo.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));
Event Broadcasting:
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()); }
}
Debugging with Dashboard:
http://your-app.test:6001 (or production URL) to monitor:
Scaling:
websockets:serve behind a load balancer (e.g., Nginx).BROADCAST_CONNECTION=redis in .env for distributed broadcasting.Authentication:
BroadcastAuthorization trait to restrict access:
class PrivateChannel extends Channel
{
public function join($connector, $channel, $request)
{
return (int) $request->user()->id === (int) $channel;
}
}
config/websockets.php:
'allowed_origins' => ['http://localhost:3000', 'https://your-app.com'],
php artisan websockets:test to simulate connections in CI.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',
],
Port Conflicts:
6001. Ensure it’s free or change it in .env:
WEBSOCKETS_PORT=6002
netstat -tulnp | grep 6001 (Linux/Mac).Redis vs. Database:
BROADCAST_CONNECTION=redis
QUEUE_CONNECTION=redis
Echo Configuration Mismatch:
wsHost in Echo matches your WebSocket server’s domain/IP.wsHost: window.location.hostname; for production, use the public URL (e.g., wss://your-app.com).Daemon Mode Quirks:
storage/logs/websockets.log. Tail the log for errors:
tail -f storage/logs/websockets.log
--daemon carefully; processes may not restart automatically on crashes.Channel Naming:
private-user.{$id}). Use PrivateChannel with authorization instead.WebSocket connection to 'ws://...' failed).allowed_origins in config/websockets.php includes your frontend URL.ShouldBroadcast and broadcastOn() returns a valid channel.storage/logs/laravel.log for broadcasting errors.Custom Middleware:
// config/websockets.php
'middleware' => [
\BeyondCode\LaravelWebSockets\Middleware\Authorize::class,
\App\Middleware\CustomMiddleware::class,
];
class CustomMiddleware
{
public function handle($request, \Closure $next)
{
if (!$request->query->has('auth_token')) {
return false;
}
return $next($request);
}
}
Event Filtering:
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
Metrics and Monitoring:
// config/websockets.php
'metrics' => [
'enabled' => true,
'port' => 9090,
],
http://your-app.test:9090/metrics.Proxy Setup:
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;
}
wsHost to /ws if using a subpath.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.http://{host}:{port} (e.g., http://localhost:6001).debug mode in config/websockets.php:
'debug' => env('APP_ENV') !== 'production',
How can I help you explore Laravel packages today?