Laravel Real-Time Notifications with SSE

April 05, 2023

Say Hi to Server-Sent Events

If you've ever needed to implement a real-time feature in your web application, you're likely familiar with the complexity of using WebSockets or the resource-intensive nature of long-polling.

Recently, I found myself in a situation where neither of them was an option, that's when I discovered Server-Sent Events (SSE), not only it was super easy to set up, but it also allowed me to achieve real-time communication in a fraction of the time it would have taken with WebSockets, and in this article, we will create a real-time notification using this technology.

How does SSE work?

sse

SSE allows a server to send real-time updates to a web page without the need for the client to constantly poll for new information.

The flow is simple, the client establishes a connection with the server, and the server sends updates to the client over that connection as they occur, these updates are sent as "events," which consist of a message and an optional event name.

The client then can react to these events accordingly, by displaying a notification or updating the page.

SSE is a good alternative to WebSockets only if your use case requires one-way communication, from Server to Client.

Let's use it in a Laravel project

Here is a preview of what we are going to build today

Installation

I will be using Laravel-Wave package to implement SSE.

Let's start by creating a new Laravel application

composer create-project laravel/laravel laravel-sse

For the server-side setup, we just need to pull the package

composer require qruto/laravel-wave

For the client-side setup, we need to install Laravel Echo and the adapter that comes with the package

npm install --save-dev laravel-echo laravel-wave

I will also install sweetalert2 for this demo

npm install --save-dev sweetalert2

Broadcast Notifications

Make sure to configure Laravel to broadcast events, docs.

Let's create a new Laravel event

php artisan make:event RealTimeNotification

We need to make a few changes to this event

  • Make sure it implements the ShouldBroadcast interface.
  • Make sure it returns Channel instead of PrivateChannel.
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class RealTimeNotification implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     */
    public function __construct(
        public string $message,
    ) {}

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn(): array
    {
        return [
            new Channel('events'),
        ];
    }
}

Now we need to configure Laravel Echo to listen to the newly created event.

In your bootstrap.js, add the following code

import Swal from 'sweetalert2';

import Echo from 'laravel-echo';

import { WaveConnector } from 'laravel-wave';

window.Echo = new Echo({ broadcaster: WaveConnector });

window.Echo.channel('events')
    .listen('RealTimeNotification', (e) => {
        Swal.fire({
            position: 'top',
            icon: 'success',
            title: e.message,
            showConfirmButton: false,
        });
    });

Now let's run Vite development server

npm run dev

Believe it or not, that's all you need to do to receive real-time notifications!

Test the notifications

First, let's add a route in our web.php

Route::view('real-time-notifications', 'sse');

In your resources/views/see.blade.php add the following code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Real Time Notifications</title>
</head>


<body>
    @vite('resources/js/app.js')
</body>

</html>

Now all that's left to do is to dispatch the RealTimeNotification event

Start tinker

php artisan tinker

Dispatch the event

event(new \App\Events\RealTimeNotification("Hello World!"))

You should see the alert popping up, like the preview above!

Conclusion

SSEs are simple to set up and use, but they may not be appropriate for every project, as they are unidirectional.

Now that you know about them, it's up to you to decide between the straightforwardness of SSEs, which come with limitations, or the versatility of WebSockets, which is usable for all use cases but complex to implement.


Profile picture

Written by Oussama Mater Software Engineer, and CTF Player.
Find me on X, Linkedin, Github, and Laracasts.