how does broadcast work in Laravel?

How Does Broadcast Work In Laravel?

Hi guys,

Broadcast is a technique in which we are sent information to multiple receipts at one time. The goal of broadcasting is to reach people as much as possible. In this article, we look at how does broadcast works in Laravel and deep dive into the functionality of broadcast.

Web sockets implement real-time, live-updating user interfaces. It provides a more robust, efficient alternative to continually polling your application for changes.

Configuration:-

You can change all configurations inside the config/broadcasting.php file pusher channels, Redis, and log drivers supported on laravel and also use a null driver for disabling broadcasting.

You will first need to register the broadcasting of any events in App\Providers\BroadcastServiceProvider. Laravel echo needs to access the current session’s CSRF token. You must add a meta tag in a head HTML element.

<meta name="csrf-token" content="{{ csrf_token() }}">

Concept Overview:-

You are allowed to broadcast your server-side laravel events to your client-side javascript application. It sent events over channels that may specify a public or private channel. Users can subscribe to a public channel without any authentication or authorization. You can subscribe private channel if you authenticate.

The ShouldBroadcast Interface:

Suppose users view their order status. We don’t want them to reload the whole page instead of updating the status. We should create a new event that implements the ShouldBroadcast interface. Look at the below code. We have made the ShippingStatusUpdated event. You should define a broadcastOn method for broadcasting events on a particular channel.

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

class ShippingStatusUpdated implements ShouldBroadcast
{
    /**
     * Information about the shipping status update.
     *
     * @var string
     */
    public $update;

    /**
     * Get the channels the event should broadcast.
     *
     * @return \Illuminate\Broadcasting\PrivateChannel
     */
    public function broadcastOn()
    {
       return new PrivateChannel('order.'.$this->update->order_id);
    }
}

For private channels, users must authorize. You may define your channel rules in the routes/channels.php file. Following the line of code, we verify the user and order creator to show the order status.

Broadcast::channel('order.{orderId}', function ($user, $orderId) {
    return $user->id === Order::findOrNew($orderId)->user_id;
});

The channel method accepts two arguments, the name of the channel and a callback function that returns true or false according to the condition defined inside the callback function.

Afterward, you need to listen to the event on the JavaScript application. We use a private method to subscribe to a private channel. We may use the listen method for listening for the ShippingStatusUpdated event.

Echo.private(`order.${orderId}`)
    .listen('ShippingStatusUpdated', (e) => {
        console.log(e.update);
    });

Defining Broadcast Events:-

You should implement the ShouldBroadcast interface in your event class and implement a broadcastOn method. The broadcastOn() method should return a channel or an array of a channel. They represent public channels that any user subscribes to, while PrivateChannels and PresenceChannels represent private channels that require channel authorization.

<?php

namespace App\Events;

use App\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

class ServerCreated implements ShouldBroadcast
{
    use SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('user.'.$this->user->id);
    }
}

You need to fire the event. It fires the event, and the queued job will automatically broadcast the event over the broadcast driver.

Broadcast Name:

You may change the broadcast name by defining a broadcastAs method in the event.

/**
 * The event's broadcast name.
 *
 * @return string
 */
public function broadcastAs()
{
    return 'server.created';
}

you may listen to channels like below:

.listen('.server.created', function (e) {
    ....
});

Broadcast Data:

When an event broadcasts, all public properties are repeatedly serialized and added to the event’s payload. It will access its public data from the JavaScript application. You want to limit control over your broadcast payload. You may add a broadcastWith() method to your event.

/**
 * Get the data to broadcast.
 *
 * @return array
 */
public function broadcastWith()
{
    return ['id' => $this->user->id];
}

Broadcast Queue:

They placed each broadcast event on the default queue for the default queue connection specified in your queue.php file. You may define the broadcastQueue property in your event class.

/**
 * The name of the queue on which to place the event.
 *
 * @var string
 */
public $broadcastQueue = 'your-queue-name';

You can make a sync queue to broadcast your event instead of the default queue driver for that you implement the ShouldBroadcastNow interface instead of ShouldBroadcast.

<?php

use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

class ShippingStatusUpdated implements ShouldBroadcastNow
{
    //
}

Broadcast Conditions:

The broadcastWhen() method is used to check the condition if it is true, thus only we broadcast the event.

/**
 * Determine if it should broadcast this event.
 *
 * @return bool
 */
public function broadcastWhen()
{
    return $this->value > 100;
}

Authorizing Channels:-

They authorize channels by making an HTTP request for your application with the channel name and allowing your application to determine if a user can listen to that channel. You need to define routes to respond to these requests.

Defining Authorization Routes:

You define the routes to respond to channel authorization requests. In the BroadcastServiceProvider, you can see the Broadcast::routes method for handling authorization requests on the /broadcasting/auth route.

Broadcast::routes();

Laravel automatically adds the broadcast::routes method inside the web middleware group. You can pass an array of route attributes to this method.

Broadcast::routes($attributes);

Echo uses /broadcasting/auth endpoint to authorize channel access. You may change the authorization endpoint using the authEndpoint option to the Echo instance.

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-channels-key',
    authEndpoint: '/custom/endpoint/auth'
});

Defining Authorization Callbacks:

We are going to perform the channel authorization on the routes/channels.php file. The channel function accepts two arguments: channel name and a callback function which return boolean values according to condition.

Broadcast::channel('order.{orderId}', function ($user, $orderId) {
    return $user->id === Order::findOrNew($orderId)->user_id;
});

The callback function obtains promptly authenticated users as their first argument and any additional parameters. You can also model instances for authorization. You may assign multiple guards to incoming requests if necessary.

use App\Order;

Broadcast::channel('order.{order}', function ($user, Order $order) {
    return $user->id === $order->user_id;
});

Broadcast::channel('channel', function () {
    // ...
}, ['guards' => ['web', 'admin']]);

Defining Channel Classes:

The best way to authorize channels is by creating channel classes. You can use the Artisan command to create a channel.

php artisan make:channel OrderChannel

use App\Broadcasting\OrderChannel;

Broadcast::channel('order.{order}', OrderChannel::class);

The join method contains an authorization condition. If it is true, then the user joins this channel.

<?php

namespace App\Broadcasting;

use App\Order;
use App\User;

class OrderChannel
{
    /**
     * Create a new channel instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Authenticate the user's access to the channel.
     *
     * @param  \App\User  $user
     * @param  \App\Order  $order
     * @return array|bool
     */
    public function join(User $user, Order $order)
    {
        return $user->id === $order->user_id;
    }
}

Broadcasting Events:-

You want to fire an event using the event function. The event dispatcher will notice and queue to an event for broadcasting.

event(new ShippingStatusUpdated($update));

When building an application that utilizes event broadcasting, you can replace the event function with a broadcast function. The broadcast function dispatches the event to your server-side listeners.

broadcast(new ShippingStatusUpdated($update));

You would exclude the current user from the broadcast function using the toOthers() method and send it to other recipients.

broadcast(new ShippingStatusUpdated($update))->toOthers();

Your event must use the Illuminate\Broadcasting\InteractsWithSockets trait to call the toOthers method. You are using Vue and Axios. It will immediately attach a socket ID to every outgoing request as an X-Socket-ID header. Laravel extracts the Socket ID from the request header, and the broadcaster will broadcast to all connections except the extracted socket ID. If you are not using Vue and Axios, you need to add the request header manually to every request. You can retrieve the socket ID using the Echo.socketId method.

var socketId = Echo.socketId();

Receiving Broadcasts:-

Listening to events:

You will use the channel method to retrieve an instance of a channel and call the listen method to listen for a specified event. You can listen for events on a private channel using the listen() method and chain calls to the listen method to listen for multiple events on a single channel.

Echo.channel('orders')
    .listen('OrderShipped', (e) => {
        console.log(e.order.name);
    });

Echo.private('orders')
    .listen(...)
    .listen(...)
    .listen(...);

Leaving a Channel:

To leave a channel, you call the leaveChannel() method. If you quit a channel and its associated private and presence channels, use the leave method.

Echo.leaveChannel('orders');
Echo.leave('orders');

Presence Channels:-

They build a presence channel with powerful, collaborative application features, such as notifying the current user when users see the same page.

Authorizing Presence channels:

When defining authorization callbacks for presence channels, you will not return true if the user is authorized to join the channel. You should return an array of data about the user.

Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
    if ($user->canJoinRoom($roomId)) {
        return ['id' => $user->id, 'name' => $user->name];
    }
});

Joining Presence Channels:

The join method will return the PresenceChannel implementation that, along with exposing the listen method, allows you to subscribe to here, join, and leave events.

Echo.join(`chat.${roomId}`)
    .here((users) => {
        //
    })
    .joining((user) => {
        console.log(user.name);
    })
    .leaving((user) => {
        console.log(user.name);
    });

The here() method will execute on joining someone to the channel. So, it will receive an array containing the user. It will run the joining method when new users join a channel. The leaving event runs when the user leaves the channel.

Broadcasting to presence channels:

We are creating a NewMessage event for the room presence channel. We will return the instance of the Presence channel from the broadcastOn method.

/**
 * Get the channels the event should broadcast.
 *
 * @return Channel|array
 */
public function broadcastOn()
{
    return new PresenceChannel('room.'.$this->message->room_id);
}

You can broadcast the information using the broadcast method and exclude the current user from receiving the broadcast information using the toOthers method.

broadcast(new NewMessage($message));

broadcast(new NewMessage($message))->toOthers();

You may listen to join the event via the Echo listen method.

Echo.join(`chat.${roomId}`)
    .here(...)
    .joining(...)
    .leaving(...)
    .listen('NewMessage', (e) => {
        //
    });

Client Events:-

You want to alert users of your application that another user is typing a message on a screen. To broadcast client events, you may use Echo’s whisper method:

Echo.private('chat')
    .whisper('typing', {
        name: this.user.name
    });

To listen for client events, you may use the listenForWhisper method:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

I hope that this post (How does Broadcast work in laravel) has helped you understand managing channels like joining channels, leaving channels, and listening to information that is broadcasted in a channel. I used this site to write this post. Please leave a remark if you have any queries, and I will answer as quickly as possible.

Thank you for reading this article. Please share this article with your friend circle. That’s it for the day. Stay Connected!
Cheers

Loading

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top