Server-Sent Events (SSE) is a great solution for enabling real-time notifications or updates in your application. Unlike WebSockets, SSE allows for one-way communication from the server to the client, making it lightweight and easy to implement. In this tutorial, we'll walk through how to set up SSE in a Laravel backend and consume the events in a Vue.js frontend.
Overview
We’ll be creating a simple real-time notification system using SSE. The server (Laravel) will push notifications to the client (Vue.js) whenever there are new notifications for the authenticated user. Here's a breakdown of what we'll cover:
- Backend (Laravel): Set up an SSE endpoint to stream notifications.
- Frontend (Vue.js): Set up an EventSource to listen for incoming notifications.
Step 1: Backend (Laravel)
1.1 Create an SSE Route in Laravel
In your routes/api.php, create an endpoint for the SSE stream. This will allow your Vue.js frontend to establish an SSE connection and listen for notifications.
use App\Http\Controllers\NotificationController;
Route::get('/notifications', [NotificationController::class, 'get']);
1.2 Controller Method for Streaming Notifications
Next, in the NotificationController, implement the logic to fetch unread notifications from the database and stream them to the client via SSE.
namespace App\Http\Controllers;
use App\Models\Notification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class NotificationController extends Controller
{
public function get(Request $request)
{
$headers = [
"Content-Type" => "text/event-stream",
"Cache-Control" => "no-cache",
"Connection" => "keep-alive",
"X-Accel-Buffering" => "no",
];
return response()->stream(function () {
while (true) {
// Fetch the unread notifications for the authenticated user
$notifications = Notification::where('clicked', 0)
->where('user_id', 2) // For now, hardcoding the user ID, you can replace it with Auth::id() for dynamic user handling
->get();
// If there are notifications, send them to the frontend
if ($notifications->isNotEmpty()) {
// Format notifications as JSON and send them via SSE
echo "data: " . json_encode($notifications) . "\n\n";
}
// Flush the output buffer
ob_flush();
flush();
// Sleep for a few seconds before checking again
sleep(5);
}
}, 200, $headers);
}
}
Explanation:
Streaming Response: The response()->stream() method is used to send an infinite stream of events.
Notifications: We are querying the Notification model for unread notifications (clicked = 0) for a specific user. The notifications are encoded as JSON and sent to the client.
Headers: The headers are set for SSE (Content-Type: text/event-stream).
Infinite Loop: The while (true) loop keeps the connection open and continuously sends new notifications every 5 seconds (adjustable by modifying sleep(5)).
Step 2: Frontend (Vue.js)
Now, let's set up the Vue.js frontend to listen for these notifications using the EventSource API.
2.1. Set Up Vue Component to Listen for SSE Events
Create a Vue component that will listen for the incoming events from the SSE stream.
<template>
<div>
<h3>Unread Notifications</h3>
<ul v-if="notifications.length">
<li v-for="notification in notifications" :key="notification.id">
{{ notification.message }}
</li>
</ul>
<p v-else>No new notifications</p>
</div>
</template>
<script>
export default {
data() {
return {
notifications: [], // Store notifications
};
},
mounted() {
// Initialize EventSource to listen to the /api/notifications endpoint
const eventSource = new EventSource('/api/notifications');
// Handle incoming events from SSE
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data); // Parse JSON data from the server
this.notifications = data; // Update notifications list
};
// Handle errors
eventSource.onerror = (error) => {
console.error("EventSource failed:", error);
eventSource.close(); // Close the connection if there's an error
};
},
beforeDestroy() {
// Close the SSE connection when the component is destroyed
if (this.eventSource) {
this.eventSource.close();
}
}
};
</script>
Explanation:
- EventSource: We create an EventSource instance that listens to the /api/notifications endpoint. This establishes a persistent connection to the server. onmessage: This event listener processes incoming messages. The data is parsed from JSON and added to the notifications array. onerror: If an error occurs (e.g., if the SSE connection is lost), we log the error and close the connection.
- beforeDestroy: To prevent memory leaks, the SSE connection is closed when the component is destroyed.
Conclusion
In this tutorial, we’ve set up real-time notifications using Server-Sent Events (SSE) in a Laravel backend and a Vue.js frontend. SSE provides a simple and efficient way to push real-time updates to the client, making it an excellent choice for features like notifications. With minimal setup, you can enhance your application with live, real-time capabilities.
Top comments (0)