در حال بارگذاری ...

Creating Test Routes0:00

Let's figure out how we can fire an event, but have it automatically broadcast to our client-side. So I'm going to switch to routes.php, and we'll set up two test routes. For example, we'll have a home page where we will just see that things were broadcast successfully, and then we need a page to actually fire the event. As an example, we'll call that broadcast. But imagine you're building some kind of project management app where you have maybe teams. And if one person is viewing the team's tasks, but another person creates a new task, well, that original person won't see the new task until they refresh the page, right? But what if it didn't have to be that way? What if we could listen for when that new task was added and automatically update the DOM?

But what if it didn't have to be that way? What if we could listen for when that new Task was added and automatically update the DOM? That's what this allows for. So let's do this right here. We're going to fire an event, and we'll just use something simple like User. Maybe you're building a reporting layer, and you want to have a dashboard that updates every single time a new User registers for your application without having to refresh the page. Let's see how we can do that. I will fire an event.

Firing a Server Event1:02

Let's see how we can do that. I will fire an event. Now you could inject the dispatcher here. You could use the facade, or you can use the global event function, which is pretty useful in some cases. So why don't we say a new User has registered. And in this case, I'll just pass through a name, but you could also pass through, if you want, like an Eloquent model where you build up a new User. Or some people don't like that idea, and they have a separate DTO object that they pass. Lots of ways to do this stuff. We'll just say Jeffrey Wei for now.

Generating Events and Listeners1:29

Lots of ways to do this stuff. We'll just say Jeffrey Wei for now. Okay, so we're firing this event, but the class doesn't exist just yet. Let's do that now. Within my providers, EventServiceProvider, you'll see our array for events that we want to listen for. Let's say when a User has registered, we want to trigger maybe some kind of email listener. Okay, well, we could say php artisan make:event and php artisan make:listener, or there's a helpful command called php artisan event:generate. And what that does is Laravel will basically scan this array and automatically call those commands for you. Let's try it.

And what that does is Laravel will basically scan this array and automatically call those commands for you. Let's try it. php artisan event:generate. And you'll now see that you have your UserHasRegistered class, and you also have the EmailListener. Now, this is sort of like a single use listener right now, and that's useful in a lot of cases. But if you want to use a single listener to handle multiple events, then maybe you could do something like this. Now, when a User registers, we will call the welcome method on the EmailListener, and we'll update this. Okay, so I'm just going to var_dump the $user, event UserHasRegistered, fire off an email.

Now, when a user registers, we will call the welcome method on the email listener, and we'll update this. Okay, so I'm just going to var_dump the user, event user, hasRegistered, fire off an email. Okay, so let's see this workflow once again. Remember, we're not yet broadcasting anything. We're just firing a standard event. When I hit this URI, we will fire an event that says a new user has registered. And specifically, I'm just passing through my own name here. But if we visit the UserHasRegistered class, in our constructor, we're not accepting that name. Let's do that now. This name equals name.

Let's do that now. This name equals name. And now I'm going to make this public like so. However, like I said, if you pass through, for example, a User object instead, what's cool is Laravel can automatically serialize that model and refetch it on the other side, which is cool. Otherwise, any public properties you have will automatically be serialized and fired or broadcast or triggered using whatever service you've picked, whether that's Pusher or Redis or something custom. All right, so we've accepted the name and we fired it. We then said when it's fired, I want to call a welcome method on my Email class.

All right, so we've accepted the name and we fired it. We then said when it's fired, I want to call a welcome method on my email class. And if we take a look at that, this method just dumps something to the screen. Let's try it out. Okay, so we will visit /broadcast. And whoops, we forgot to import that class. There we go. Okay, one more time. And this time, sorry, a little mistake on my part. We picked up the event, but I called it user when actually we called it name right here.

And this time, sorry, a little mistake on my part. We picked up the event, but I called it user when actually we called it name right here. Okay, stupid little mistakes. But sure enough, we can see that we fired an event, we listened for it, and then we responded accordingly. But all of this is taking place on the server side. Now, in addition to this, I also want to tell Laravel to broadcast this event to my client side. Here's how we do that. First, if I go into my config directory, in Laravel 5.1, you'll see this broadcasting file. And what's nice about this is you can broadcast using any service you want. By default, it'll use Pusher, which is great.

Configuring Pusher Broadcasting4:35

And what's nice about this is you can broadcast using any service you want. By default, it'll use Pusher, which is great. I use it for Laracasts. Works really well and is very simple. But alternatively, you could use Redis. You could use the logger if you're working in just development mode. It's pretty flexible. So we're going to stick with Pusher, but we do need to provide our Pusher key, secret, and app ID. Notice that it references the environment function, which means right down here I can reference these. Pusher key, and then Pusher secret, and then finally Pusher app ID.

And then finally, my app id is right here. Done. Next, if we're going to use Pusher, well, Laravel doesn't include the Pusher SDK out of the box. Instead, you'll need to grab that yourself. And remember, all of this stuff is listed in the documentation. For example, if we switch over, let's search for Pusher on the events page. And yeah, there we go. If we're going to use Pusher, we need to pull in the library. composer require, and let's grab that.

If we're going to use Pusher, we need to pull in the library. composer require, and let's grab that. There we go. Okay, so we've set up our Pusher keys. In our broadcasting section, we've specified that we want to use Pusher, and it's set that way out of the box. Finally, we have to tell Laravel which events should be broadcast. Some of them should, and others, well, you don't need to broadcast that to the client side. Now, if we take a look at our event class, you'll see that we have this shouldBroadcast interface.

Now, if we take a look at our Event class, you'll see that we have this ShouldBroadcast interface. Now, here's what's cool. If I simply say implements ShouldBroadcast, behind the scenes, Laravel's going to check for that, and I'll show you where in just a minute. But basically, it's going to see, okay, this event object implements this interface. So that means the user does want to trigger this event using the driver they selected, which is Pusher. So I'm going to go ahead and reference the Pusher SDK.

which is Pusher. So I'm going to go ahead and reference the Pusher SDK and use its API all behind the scenes to trigger this event that you gave me. Now, as for the data that I will pass through when I trigger it, well, I'm going to serialize all of these public properties for the User. So now, what's the next step? We've taken care of basically all of the php side, other than this one section where we specify the channel that we want to broadcast on. We'll come back to that. So let's set up the JavaScript end.

Subscribing via JavaScript7:25

We'll come back to that. So let's set up the JavaScript end. Here, why don't we just load the welcome view that comes out of the box. If we take a look at that, welcome, we can get rid of basically all of this stuff. Okay, now what do we use in its place? Well, let's go back to the Pusher documentation, and you'll see they actually have some good code examples. So we pull in the Pusher library. Let's grab that. Next, we'll see that we create a new Pusher object.

Let's grab that. Next, we'll see that we create a new Pusher object. And remember, you have that Pusher global because of what you just imported. Okay, so we instantiate Pusher. We pass through our publicKey, and then we do say that we want all of the data encrypted. So let's do that right here. And next, you know, you don't really want a bunch of globals here, so let's wrap this in a function and then automatically trigger it. You'll see that referred to as like a self-invoking anonymous function.

so let's wrap this in a function and then automatically trigger it. You'll see that referred to as like a self-invoking anonymous function or a self-executing function, whatever. Okay, so we have our Pusher instance. Next, we subscribe to a channel. I like to think of this as like one of those old TVs where you turned the knob to switch to the eight channels that you had back in the day. So if we want to listen for an event, we first have to turn that knob to the channel that the event is broadcast on. Otherwise, you would never hear it,

we first have to turn that knob to the channel that the event is broadcast on. Otherwise, you would never hear it, just like you will never see one TV show if you're turned to a different channel. Does that make sense? So let's try it. $channel, and we are going to subscribe to whatever channel we want. Maybe you have a generic channel like Forum, or maybe you want to listen for a channel specifically for a User with an ID of five. That would be fine. Or maybe a channel for tasks specifically for a group.

That would be fine. Or maybe a channel for tasks specifically for a group. You can modify this however you want. We're going to stick with test. So now you might be thinking, okay, on your JavaScript side, you've turned the knob, right? You've changed to a new channel. But how does your server side know to broadcast on that channel? Well, that's where we come back to our User hasRegistered class. We've noted that it should broadcast,

Well, that's where we come back to our UserHasRegistered class. We've noted that it should broadcast, and if we look at the interface, it has one method, broadcastOn. So you'll see that our boilerplate includes that. This represents one or more channels that you want to announce this event on. We're going to stick with test. Fire this event on the test channel, and then on our JavaScript end, switch the knob or change the channel to the one called test. The final step is we've turned the channel.

and on the server side where they fire the event, they use a different name. We don't need to worry about that. We already have a good event name, UserHasRegistered. So on your client side, that's what you listen for, the full class path, App\Events\UserHasRegistered. Okay, so let's say right here, welcome, and let's see how this all works. So quick recap, we load the home page that displays this, where we instantiate Pusher and we subscribe to the UserHasRegistered event. That connection is now open and listening. Next, we hit this broadcast URI in a different tab,

That connection is now open and listening. Next, we hit this broadcast URI in a different tab, and all that does is fire an event called NewUserHasRegistered, and I'll say done. User has registered specifically says that it wants to broadcast to the client side, and specifically to the channel called test. So let's see if it all works. Back to Chrome, I'm going to open up my Chrome DevTools with Shift + Command + C, and then within a new tab, we will hit that broadcast URI. Okay, so if I come back, sure enough, you can see this object here,

and then within a new tab, we will hit that broadcast URI. Okay, so if I come back, sure enough, you can see this object here, and every time I hit it, let's do it two, three more times, you'll see three more objects, and notice that this page did not have to be refreshed. How cool is that? So why don't we make this a little more fun and say within routes.php, the actual name we'll just grab from the request, you know, just to have something a little bit different. Okay, so let's give that a refresh, and now we'll say name is Frank,

you know, just to have something a little bit different. Okay, so let's give that a refresh, and now we'll say name is Frank, name is John, name is Susan, and name is Sandy. Okay, now we should have four objects, and sure enough, we do. So think about really how cool that was. When it comes to your server side, all you do is fire an event like you always do. There's really no difference at all other than the fact that on your event object, just note that you're implementing an interface, and then specify which channel we should broadcast on. That's literally all you have to do.

and then specify which channel we should broadcast on. That's literally all you have to do. And actually, on that note, let me prove it to you. Let's do this. Let's search. If you ever can't find something, just search for the relevant bits. For example, if you want to see where Laravel listens or checks to see if you implement this interface, then just search for shouldBroadcast, and if we scroll down a ways, this looks like the right section.

then just search for shouldBroadcast, and if we scroll down a ways, this looks like the right section. Here we're in the event dispatcher, notice eventFire, and if we scroll down, yeah, so our payload, remember if we say, for example, eventFire, and then our newUser has registered, okay, well that's the first item in that payload array, and we're checking to see did the User add implement shouldBroadcast, and if they did, once again, they want to broadcast it, so we call broadcastEvent,

and if they did, once again, they want to broadcast it, so we call broadcast event, and then for our queue connection, we push broadcast event. Let's take a look at that. broadcast event, and here's where we fire it, and notice this broadcaster broadcast. So this is referencing whatever concrete implementation of the broadcaster you want. Remember how we selected pusher? Well, that means there's a pusher broadcaster,

Remember how we selected pusher? Well, that means there's a pusher broadcaster, and it implements this interface, and if we scroll down to see how we broadcast with pusher, we'll check this out. This pusher, we're referencing that pusher SDK we pulled in, and then we call a trigger method on it. Now, if we go back to the pusher docs, let's look at the PHP information, instantiate pusher, and then call pusher trigger channel event data.

let's look at the php information, instantiate Pusher, and then call trigger channel event data. It's the exact same thing. Laravel's just abstracting it away behind an interface, and then here, it just says whichever one the user selected, we don't care, just whatever implementation they chose, let's go ahead and broadcast it and send through the necessary data, and then finally, we delete the Qt job. So yeah, and you don't even really need to know how this works, but if you're anything like me,

Updating UI with Vue14:26

So yeah, and you don't even really need to know how this works, but if you're anything like me, I'm always curious to see what's happening behind the scenes. Okay, so to finish up, well, why don't we display these users, and why don't we use something like Vue.js, since we cover that a lot in this series. So I will import that, and let's come to this out for the time being, and start again. We will create a new Vue instance.

and start again. We will create a new Vue instance. We're going to bind it to our users. Let's create that up here. Next, we'll say when we're ready to go, why don't we go ahead and instantiate pusher, or if you want, you can do this someplace else, whatever you want, and then we say pusher.subscribe to the test channel, and now, let's listen or bind,

and then we say pusher.subscribe to the test channel, and now, let's listen or bind, and we're going to listen for the app events User has registered events, and when you catch that or when it's fired, it's going to send through the User who registered, and specifically, what do we want to do here? Well, we just want to add a User, so why don't we say instead this.addUser, and then we'll reference that here, and user, accept the user,

and then we'll reference that here, and user, accept the user, and then maybe we'll update a list of users that we have, maybe something like that. All right. So when we add a user, we'll say this.users.push(user). Finally, we want to display the users, so maybe this is a <ul> instead, and we'll say <li>.

so maybe this is a ul instead, and we'll say listItem. We're going to repeat User and users, and we will echo out the user's name. Now remember, I'm calling user.name because within our event object, we have the public name property, and that's what I mean when I say Laravel serializes everything and then sends it through so that you can interact with it in basically the exact same way.

but I will never refresh this tab. Okay. Name is Sandy. Hit that, and it updates. Name is Jeff. Name is Taylor. You get the basic idea. Somebody on the other side of the world can take some action that triggers an event on your server. Your server then fires an event, in our case, using Pusher,

Your server then fires an event, in our case, using Pusher, which we then listen for anywhere, and when we catch it, we update our list of users, and that's all there is to it. I love it.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟