The Flow
- A user visits a page with the notification component.
- The Vue component opens an SSE connection to a specific Laravel route (e.g.,
/notifications/stream). - The Laravel controller keeps this connection open.
- When a new
Notificationis created in your MongoDB collection, theNotificationObserverfires. - The observer’s
createdmethod will write the new notification data to the cache with a user-specific key. - The
SseController, in its long-running loop, detects the new cache entry, sends it down the stream to the browser, and then deletes the cache entry. - Vue’s
EventSourcelistener receives the data and updates the UI in real-time. - The “Refresh” button will call a separate, standard API endpoint to fetch all notifications, just like your old polling mechanism.
Step 1: Backend - The Model and Observer
First, let’s set up the model and the observer that will react to new database entries.1a. Notification Model
I’ll assume you are using thejenssegers/laravel-mongodb package. Your model might look something like this.
app/Models/Notification.php
1b. Create the Observer
This is the core of the trigger mechanism. Generate the observer using Artisan:created method. It will write the new notification to the cache. The cache acts as a fast, temporary message queue between the web request that created the notification and the SSE process.
app/Observers/NotificationObserver.php
uniqid() to ensure that if two notifications are created for the same user before the SSE loop runs, both are stored in the cache under different keys.
1c. Register the Observer
You must register the observer in a service provider. The best place isEventServiceProvider.
app/Providers/EventServiceProvider.php
Step 2: Backend - The SSE Controller and Route
This controller will handle the persistent connection.2a. Create the Controller
2b. Implement the SSE Logic
We’ll use Laravel’sStreamedResponse to send data without closing the connection.
app/Http/Controllers/SseController.php
Important: The cache scanning part is not very performant with thefileordatabasecache drivers. For production, you should strongly consider usingredis:CACHE_DRIVER=redisin your.envfile. With Redis, you could useCache::keys($cachePrefix . '*')which is much more efficient.
2c. Define the Route
This route must be protected by authentication middleware.routes/web.php
Step 3: Backend - Manual Refresh Endpoint
This is the standard endpoint that the “Refresh” button will use.3a. Create the Controller
3b. Implement the Index Method
This method simply fetches all notifications for the current user.app/Http/Controllers/NotificationController.php
Step 4: Frontend - The Vue 2 Component
Now let’s create the Vue component that consumes the SSE stream and provides the manual refresh button.resources/js/components/NotificationBell.vue
<notification-bell></notification-bell> component anywhere in your Vue application. You’ve successfully replaced polling with a real-time SSE push system while retaining the ability to manually refresh.