bugover/laravel-websocket
Fork of beyondcode/laravel-websockets bringing WebSockets to Laravel as a drop-in Pusher replacement. Supports SSL, Laravel Echo, and a debug dashboard, plus added connection events and two-way client-to-server messaging.
Installation:
composer require bugover/laravel-websocket
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan migrate
Configure Broadcasting:
Update config/broadcasting.php:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'host' => env('PUSHER_HOST', '127.0.0.1'),
'port' => env('PUSHER_PORT', 6001),
'scheme' => env('PUSHER_SCHEME', 'http'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME') === 'https',
],
],
Start Server:
php artisan websockets:serve
Test Connection: Use Laravel Echo in your frontend:
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
wsHost: window.location.hostname,
wsPort: 6001,
forceTLS: false,
disableStats: true,
});
Publish an Event:
// In your controller or command
event(new NotificationSent($userId, $message));
Listen in Frontend:
Echo.channel(`user.${userId}`)
.listen('NotificationSent', (data) => {
console.log('New notification:', data);
});
// Publish an event to all listeners
broadcast(new App\Events\ChatMessage($message))->toOthers();
// Or via facade
event(new App\Events\ChatMessage($message));
// Private channel (authenticated users)
broadcast(new ChatMessage($message))->to($user);
// Presence channel (track online users)
broadcast(new UserOnline($user))->toOthers();
// Send data to server
const socket = new WebSocket(`ws://${window.location.hostname}:6001/app/${appId}`);
socket.onopen = () => socket.send(JSON.stringify({ event: 'customEvent', data: { key: 'value' } }));
BaseController:
namespace App\Http\Controllers;
use BeyondCode\LaravelWebSockets\Contracts\WebSocketController;
class CustomWebSocketController extends BaseController implements WebSocketController
{
public function onMessage($connection, $message)
{
$data = json_decode($message, true);
if ($data['event'] === 'customEvent') {
// Process data and broadcast response
broadcast(new CustomResponse($data['data']))->to($connection);
}
}
}
Register in websockets.php:
'controllers' => [
'App\Http\Controllers\CustomWebSocketController',
],
use BeyondCode\LaravelWebSockets\Events\Connections\ConnectionConnected;
use BeyondCode\LaravelWebSockets\Events\Connections\ConnectionDisconnected;
// In EventServiceProvider
protected $listen = [
ConnectionConnected::class => [
'App\Listeners\LogConnection',
],
ConnectionDisconnected::class => [
'App\Listeners\LogDisconnection',
],
];
apps in websockets.php:
'apps' => [
[
'id' => 'myapp',
'name' => 'My App',
'key' => 'app_key',
'secret' => 'app_secret',
'capacity' => 1000,
'enable_client_messages' => true,
],
],
broadcasting.php.Echo.connector.pusher.config.host = 'your-websocket-domain';
Echo.connector.pusher.config.port = 6001;
/laravel-websockets (enable in websockets.php).storage/logs/laravel-websocket.log for server-side issues.'channel_manager' => 'redis',
'redis' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', 6379),
'password' => env('REDIS_PASSWORD', null),
],
pecl install ev for >1024 connections.openssl req -x509 -newkey rsa:4096 -keyout local_cert.key -out local_cert.pem -days 365 -nodes
websockets.php:
'ssl' => [
'local_cert' => storage_path('app/ssl/local_cert.pem'),
'local_pk' => storage_path('app/ssl/local_cert.key'),
'passphrase' => null,
],
Connection Limits:
stream_select event loop caps at 1,024 connections. Symptoms: Dropped connections or timeouts.pecl install ev and set event_loop=ev in websockets.php.CORS Issues:
allowed_origins in websockets.php is misconfigured.allowed_origins to your frontend domain(s):
'allowed_origins' => [
'https://your-app.com',
'http://localhost:3000',
],
Missing Pusher Credentials:
PUSHER_APP_ID, PUSHER_APP_KEY, PUSHER_APP_SECRET in .env.Database Stats Overhead:
enable_statistics adds ~10ms latency per connection. Disable in production if unused:
'enable_statistics' => env('APP_ENV') !== 'production',
Channel Manager Mismatch:
ArrayChannelManager in production with high channel counts (>10K) causes memory leaks.'channel_manager' => 'redis',
Two-Way Messaging Not Working:
enable_client_messages is true for the app and the controller implements WebSocketController.storage/logs/laravel-websocket.log for unhandled messages.SSL Errors:
location / {
proxy_pass http://127.0.0.1:6001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Check Connection Status:
curl -N http://localhost:6001/apps/{app_id}/channels/private-test-channel
Monitor Processes:
ps aux | grep websockets
capacity exceeded).Log Levels:
Adjust in websockets.php:
'log_level' => 'debug', // 'debug', 'info', 'warning', 'error'
Simulate High Load:
Use websockets:load-test:
How can I help you explore Laravel packages today?