Real-time Features with WebSockets
WebSockets in Svelte + Laravel
Real-time features enhance user experience by providing immediate feedback and updates without requiring page refreshes. This guide explains how to integrate WebSockets between your Svelte frontend and Laravel backend.
WebSocket Basics
WebSockets provide a persistent connection between client and server, allowing bidirectional communication.
Native WebSocket API
// Basic WebSocket connection in JavaScript const socket = new WebSocket('ws://example.com/socket'); // Connection opened socket.addEventListener('open', (event) => { console.log('Connected to WebSocket server'); socket.send(JSON.stringify({ type: 'auth', token: 'user-token' })); }); // Listen for messages socket.addEventListener('message', (event) => { const data = JSON.parse(event.data); console.log('Message from server:', data); }); // Connection closed socket.addEventListener('close', (event) => { console.log('Disconnected from WebSocket server'); }); // Handle errors socket.addEventListener('error', (event) => { console.error('WebSocket error:', event); });
Laravel WebSocket Options
Popular Laravel WebSocket Solutions
- Laravel Echo + Laravel WebSockets - Open-source WebSocket server for Laravel
- Laravel Echo + Pusher - Pusher is a hosted WebSocket service with a generous free tier
- Laravel + Socket.IO - Using Socket.IO with Laravel for real-time features
Laravel WebSockets Setup
# Install Laravel WebSockets package composer require beyondcode/laravel-websockets # Publish the configuration and migrations php artisan vendor:publish --provider="BeyondCodeLaravelWebSocketsWebSocketsServiceProvider" --tag="migrations" php artisan vendor:publish --provider="BeyondCodeLaravelWebSocketsWebSocketsServiceProvider" --tag="config" # Run migrations to create the websockets tables php artisan migrate # Install Laravel Echo and dependencies npm install laravel-echo pusher-js
Laravel Broadcasting
Laravel's event broadcasting system integrates with WebSockets to send server-side events to the client.
Configure Broadcasting in Laravel
// config/broadcasting.php 'connections' => [ 'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'host' => env('PUSHER_HOST', '127.0.0.1'), 'port' => env('PUSHER_PORT', 6001), 'scheme' => env('PUSHER_SCHEME', 'http'), 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', ], ], ],
Create a Broadcast Event
// Create an event php artisan make:event NewMessage // app/Events/NewMessage.php namespace AppEvents; use IlluminateBroadcastingChannel; use IlluminateBroadcastingInteractsWithSockets; use IlluminateBroadcastingPresenceChannel; use IlluminateBroadcastingPrivateChannel; use IlluminateContractsBroadcastingShouldBroadcast; use IlluminateFoundationEventsDispatchable; use IlluminateQueueSerializesModels; class NewMessage implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $message; public function __construct($message) { $this->message = $message; } public function broadcastOn() { return new Channel('chat'); } }
Broadcast the Event
// In a controller or service use AppEventsNewMessage; public function sendMessage(Request $request) { $message = [ 'user' => auth()->user()->name, 'text' => $request->input('message'), 'time' => now()->toTimeString() ]; // Broadcast the event broadcast(new NewMessage($message))->toOthers(); return response()->json($message); }
Svelte + Laravel Echo Integration
Setting Up Laravel Echo in Svelte
// src/lib/echo.js import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; // Make Pusher available globally window.Pusher = Pusher; // Initialize Laravel Echo const echo = new Echo({ broadcaster: 'pusher', key: import.meta.env.VITE_PUSHER_APP_KEY, cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, wsHost: import.meta.env.VITE_PUSHER_HOST || window.location.hostname, wsPort: import.meta.env.VITE_PUSHER_PORT || 6001, forceTLS: (import.meta.env.VITE_PUSHER_SCHEME || 'https') === 'https', disableStats: true, enabledTransports: ['ws', 'wss'], }); export default echo;
Using Echo in a Svelte Component
<script> import { onMount, onDestroy } from 'svelte'; import echo from '$lib/echo'; let messages = []; let channel; onMount(() => { // Subscribe to the channel channel = echo.channel('chat'); // Listen for the NewMessage event channel.listen('NewMessage', (event) => { messages = [...messages, event.message]; }); }); onDestroy(() => { // Clean up the subscription if (channel) { channel.unsubscribe(); } }); // Send a message async function sendMessage(text) { try { await fetch('/api/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ message: text }) }); } catch (error) { console.error('Error sending message:', error); } } </script>
Private and Presence Channels
Authentication for Private Channels
Private channels require authentication to ensure only authorized users can subscribe.
// Laravel routes/channels.php Broadcast::channel('private-chat.{id}', function ($user, $id) { return $user->id === (int) $id || $user->hasAccessToChat($id); }); // Svelte component <script> import echo from '$lib/echo'; onMount(() => { // Subscribe to a private channel const privateChannel = echo.private(`chat.${userId}`); privateChannel.listen('NewMessage', (event) => { messages = [...messages, event.message]; }); }); </script>
Presence Channels for User Awareness
Presence channels track who is subscribed, making them perfect for user presence features.
// Laravel routes/channels.php Broadcast::channel('presence-chat.{roomId}', function ($user, $roomId) { if ($user->canJoinRoom($roomId)) { return ['id' => $user->id, 'name' => $user->name]; } }); // Svelte component <script> import echo from '$lib/echo'; let users = []; onMount(() => { // Subscribe to a presence channel const presenceChannel = echo.join(`presence-chat.${roomId}`); // When someone joins presenceChannel.here((members) => { users = members; }); // When someone joins after we've joined presenceChannel.joining((user) => { users = [...users, user]; }); // When someone leaves presenceChannel.leaving((user) => { users = users.filter(u => u.id !== user.id); }); }); </script>
Interactive WebSocket Demo
This demo simulates a real-time chat application using WebSockets. It's not connecting to a real server but demonstrates the concepts.
Real-time Chat Demo
Real-time Notifications
Notifications (0)
No notifications
Note: This demo simulates notifications being pushed from the server. Connect to see new notifications appear automatically.
Common Real-Time Features
SaaS Real-Time Use Cases
- Chat and Messaging - Real-time communication between users
- Notifications - Instant alerts for user actions or system events
- Live Data Updates - Dashboard with real-time metrics
- Collaborative Editing - Multiple users editing the same document
- Status Indicators - Show which users are online or currently active
- Real-time Validation - Instant feedback during form completion
Best Practices
WebSocket Tips
- Always Handle Reconnection - Implement robust reconnection logic
- Optimize Payload Size - Send only the necessary data
- Authentication - Secure your WebSocket connections
- Fallback Mechanisms - Have a plan B if WebSockets aren't available
- Error Handling - Gracefully manage connection issues
- Testing - Test WebSocket functionality thoroughly