js. However, let's ingrain things even further in your mind by taking a look at a little bit more realistic example. That is sending real-time messages between two different users. Well, actually, we're just gonna do anonymous users so that nobody actually has to log in.
but it will be still a more realistic scenario. Okay, so just as before, we want to start out by creating a new Laravel event. I'll do that with phpArtisan makeEvent, and we'll name this event messageReceived. So essentially, we're going to broadcast this event whenever a new message comes into our system.
So messageReceived makes sense. I will open up the event file. And then we will make sure the message received class implements the proper interface, that is should broadcast. This time I want to have a variable message passed in.
So in the constructor, I'll say message here, and then we'll set a public property on the class message equal to that which comes to the constructor. I also want to add an ID in here. so that we can uniquely identify each message, and you'll see why this is important in a moment. That means we also need to define the properties on the class.
Finally, down inside of the broadcast on function, once again, we're going to publish everything publicly so that anybody could subscribe to this. So I'll change private channel to channel, and then we're going to call our channel name messages in this case. All right, so the event itself is called message received. The channel is called messages.
This makes sense. We could have other events happen on this messages channel. Maybe we also wanted to send an event when a message was deleted or if a message is updated. If that was the case, we would probably want to put them on the same channel.
Now let's go back to our visit count page. just so that we don't have to set up a brand new page and route. And let's reuse this now to send messages back and forth. The first thing I'll do is get rid of the logic and the listeners for the count.
Now I want to store some messages as a reactive array. Okay, so these will be all the messages that should display to the screen. that either I myself have written in the current browser tab or another user or me in the different browser window actually is going to send and broadcast. Okay, so this will hold all of our messages.
Then I will also create a reactive variable just to bind to a text area to hold the message that I'm currently writing. Down inside the template, let's support this reactive data. id. Remember, in our event, we are going to be using IDs to uniquely identify each message.
message. Because each one will have an ID and a message, we'll print out the actual wording there. Maybe I could have named that better, but you get the idea. So now we have each of the messages displayed on the screen.
Let me also add a text area here, and we will bind this two ways with vModel to the message data. Now we need to create a form that we can submit to handle sending a new message to the server. So I'll add a form here, surrounding the text area, we'll add a new button called Send Message, and then on form submit, we will prevent the default behavior and call a function handle submit. So here on handle submit, what we want to do is add our new message to the messages array, right?
So this handles getting the local message sent where it needs to be sent. push this new message. And really we need to push an object because we need it to have an ID and the actual message text. So we will break this up to look like this.
For the ID, I will just randomly generate a UUID with the built-in browser crypto module. Then we will say the message is that string that was bound to the text area. So, so far we have nothing going back to the server and nothing coming in from the server. But let's just see if our kind of local implementation here works.
So if I type in the text area and then hit Send Message, indeed the new message is added to the list of messages above. If I type something else, Hello World 2, and hit Send Message, nice, that works too. Our styling is absolutely atrocious, but I'm not too worried about it. This gets the point across.
Okay, so now how are we going to alert the server that a new message has been sent? And how are we going to listen to that message receive event on the client to be notified whenever a new message is received from someone typing in a different browser window? The communication from the browser to the server is the easy part. This is just a classic API endpoint.
So what I wanna do here is whenever we submit the form, I'm going to use Axios, which is already on the window to post, send a post request to a slash messages endpoint. And what we wanna send to that messages endpoint is actually this message right here that we passed on to the messages array. So I will store that temporarily here under a variable called MSG. we will grab the object, push the MSG message to the messages array, and then send that same message object to the server.
Right now, this really isn't going to do anything because I don't have a messages API endpoint set up. php. So here I'll use classic Laravel routing in order to create a handler for anything that comes in with the post method and to the messages wrapped. I will use just an inline function here to describe our handler so that I don't have to set up a full controller and things like that for this simple example.
Next, I'll use request validate in order to ensure that we have both the message and the ID property sent to the server. So here we've got message is required and then ID is also required. Out of this, I can get the payload of the request. Perfect.
Now, here comes the question, what do we do with this new information? Well, in more real life applications, you would probably end up saving this to the database and then sending the message, emitting the event only to particular users. I don't want to have to mess with the database for this course because it's not necessary. Instead, I just want to dispatch our message received event.
That way other browser windows or anybody else who's visiting this same app, if I were hosting it live, would be able to get any of the messages that were sent. So I will do messages received dispatch. And remember our constructor takes in first the actual message. So that's payload message.
And then it also takes in the ID. So that's payload ID. Finally, I'll just return a JSON response that says that we've successfully received the message. So now we should be posting our messages correctly.
Let's try things out in the browser and let's just see if the network request is being made. This time we don't want to filter by WebSocket because remember this is just a regular API request. So we'll filter by fetch slash XHR instead. I'll type out a new message, hit send.
And yeah, sure enough, we have messages here. So this is the slash messages route. You can see that right here. Let's take a look at the payload.
We did indeed send a randomly generated UUID. and we have the message that's typed in the input. As a response, we do get the message, message received, just like we returned in the code. This looks like everything is going to work swimmingly.
So the last thing we need to do then is to actually listen for this message received event on the client side. View, we'll use echo. to listen to the messages channel and then listen for the message received event. When that event is fired, I'll pass the new message into the messages reactive array.
So back in the browser now, let me open up two different browser windows, but both to the visit count page. And this time when I send a message on the left-hand side and hit send message, Indeed, we get the message on the right-hand side. So this could be, of course, some totally different person's computer. However, we do have an error here.
We are getting this same message twice. That's because I'm pushing it locally into that array here, but I'm also listening for the event. There are multiple different ways I could handle this issue, but the way I want to do it... is by just checking to see if the ID already exists inside of the messages array.
And if it does, we'll just ignore pushing the new one in. find. And I want to find the message whose ID is equal to the message ID that comes through the event. So if that does not already exist, then we will push the message from the event.
into the messages array. Back in the browser now, give both pages a refresh, say hello over here, and perfect. Now we've got hello on both sides. One other thing I'd like to do is tell who the message is from.
So right now we don't know if we sent this hello message or if it came in from the other user. That's easy enough to fix. Here on submit what I'll do is I'll add one more property to our message object So we'll spread that message there and then we'll say who? who so that we can see who sent what message.
Now, when I type hello and send it, you can see that I sent this message and the other person can see that someone else sent this message. Now, of course, in a real life chat app, you probably want to know exactly the name of the person and that gets into authentication. But that's as simple as layering in some user data on top of this functionality that we've already built. So there you go.
js.