Home » Php » php – Laravel Echo private channel with Laravel echo server | Redis

php – Laravel Echo private channel with Laravel echo server | Redis

Posted by: admin July 12, 2020 Leave a comment

Questions:

Scenario: A customer can refer a client to another customer.
Each referral needs to be stored in a DB table row. The customer receiving the referral should see a notification for the event.

Create a new referral and dispatch the event:

$totalRefers = [];

foreach ($array as $to) {
    $refer = new ClientReferral;
    $refer->user_id = $user_id;
    $refer->by = $by;
    $refer->to = $to;

    $refer->save();
    array_push($totalRefers, $refer);

    ReferralSent::dispatch($refer); // Here is the Event
}

return response()->json([
    'status' => 'Success',
    'message' => 'Client referred successfully to selected professionals.',
    'data' => $totalRefers
], 200);

The event broadcastOn() method:

public function broadcastOn() {
    return new PrivateChannel('referral.' . $this->referral->id);
}

The channel:

Broadcast::channel('referral.{id}', function ($user, $id) {
    // let's say it's true for the time being
    return true;
});

And the request is an Ajax POST so in the success callback:

console.log('referral created');
res.data.forEach(function(entry) {
    // window.custom.userId is the authenticated user ID:
    if (entry.refer_to == window.custom.userId) { 
        window.Echo.private('referral.' + entry.id).listen('ReferralSent', ({data}) => {
            console.log('You have received a new referral');
        });
    }
});

Now the issue with the current code is that the receiver cannot subscribe to this channel because the event is created dynamically, and I cannot make the channel name static because the referral came in at run time.

How can a receiver subscribe and listen to dynamic events?

With this logic, I want to get that specific referral and its data to show it in the notification tray in HTML.

How can I achieve this?

How to&Answers:

The event shown in the question broadcasts to a channel for that specific referral entity only. However, the receiver that subscribes to this channel should receive events for all referral entities referred to them.

Instead of creating the channel context for the referral entity itself, publish to a channel designated for the user that receives the referral. I’m guessing that $referral->to contains that user’s ID:

public function broadcastOn()
{
    return new PrivateChannel('referral.' . $this->referral->to);
}

Update the channel to authorize the current user based on the ID of the user that receives the referral:

Broadcast::channel('referral.{refereeId}', function ($user, $refereeId) {
    return $user->id == $refereeId;
});

And, on the client-side, listen on the same channel:

window.Echo.private('referral.' + window.custom.userId)
    .listen(e => console.log(e.referral));

Because we’re not listening for a specific referral ID anymore, we can initialize the Echo subscriber during the page load instead of in the AJAX response callback.

Broadcast events are designed to be useful for real-time actions outside the normal request/response cycle (including AJAX requests). In the case of this question, we want to start Echo listeners for every customer when the page loads—not after a specific request—so that they can receive notifications any time another customer refers a client to them.

The flow looks like this:

  1. Customer 1 and Customer 2 both open the app, which starts Echo on the client-side.
  2. Customer 1 creates a referral for Customer 2.
  3. Customer 1’s browser sends an AJAX request to save the referral.
  4. Laravel publishes the event to Customer 2’s channel.
  5. Customer 2’s browser receives the event through Echo, which is listening on that channel.
  6. The code you wrote to handle that event creates a notification in Customer 2’s browser.