Laravel Echo private channel with Laravel echo server | Redis
Asked Answered
B

1

7

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?

Bandanna answered 3/9, 2018 at 10:48 Comment(2)
1. "Now the issue with the current code is that the receiver cannot subscribe to this channel" what do you mean by "this channel" ? 2. "With this logic, I want to get that specific referral" what is "that specific referral" ? 3. "that specific referral and its data" what includes in this data ?Cowbird
i don't see any problem with your code. you have everything, if you need extra data to be shown in front, send that data in callback, parse it and show. if i am mistaken, can you rephrase your problem to simple words ?Cowbird
I
4

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.
Iams answered 6/9, 2018 at 22:10 Comment(2)
Seems file but how will i return the created referral to window.Echo.private(....Bandanna
@Grammer By default, Laravel serializes the event's public properties. For example, if the event contains the $referral property, we can access it using the same property on the client-side. I updated the last example to show this.Iams

© 2022 - 2024 — McMap. All rights reserved.