LARACON EU 2024 // JOE DIXON :: REAL-TIME LARAVEL

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
please a big Applause for Joe [Music] [Applause] Dixon all right hello everybody I tell you the first thing I needed to come on stage this morning was a nice salty mouthful of yeast extract when my mouth's going to be pretty dry throughout this anyway um but yeah good morning hope you've all uh slept well had a nice evening um not sure if you feel more nervous right now coming on stage or yesterday when Taylor let you lot loose with the Emoji buttons on the Reverb website but seemed like that went pretty well so I just want to kick off things this morning as we do every morning in the naral team by saying good morning and I forgotten the sound pretend you didn't see that now I can't type I we got to say good morning James morning Dre morning Jess appreciate the support but not a great time so I am Joe and as conecta say I am one of the laral core team in case you didn't realize that's me there on the right hand side I work predominantly on Vapor laravel's servus deployment platform uh but more recently I've been kind of spreading my wings a little bit and I want to talk to you a bit more about that today I live with my wife and two kids in a small City in the UK called Norwich where we're lucky enough to have two Cathedrals one castle and the best football team in the world which is great for me because when I'm not behind the keyboard I enjoy to watch football almost as much as I enjoy Formula 1 how good he got a along almost as much as I love to drink coffee and that's really all there is you need to know about me so let's kick off proceedings this morning by addressing the elephant in the room and I know you probably all sat there thinking Joe I came away to laran to take a a break from slack why have you brought me straight back here and I promise you there's a good answer for that but also just count yourselves lucky that I didn't subject you to a session played out in teams so the good reason for why we're in slack today is that we're going to be talking about real-time laravel and how we can use the tools in laravel and the surrounding ecosystem to build really really engaging realtime uh user interfaces and so I haven't brought a keynote presentation here today I haven't brought a PowerPoint presentation or Google Slides or anything like that my slide deck is an app built with the tool stack now in case you've been living under a rock the tool stack is laravel Livewire Alpine JS and Tailwind CSS and throughout the course of this morning the next I don't know 27 minutes or so we're going to be talking about we're going to be using this skeleton application um and bringing it to life bringing in realtime communication ation elements and there's a number of different technologies that we can use to build realtime communication but today I want to talk about in particular about websockets so I'm going to jump over here into the websockets channel and we probably want to know a little bit more about what websockets are so let's see if we can ask the team what are web sock can't type on stage fingers are not working oh good open eyers the chat so this should be helpful so websockets provide a full duplex Communication channel over a single long-lived connection between a client usually a web browser and a server this allows for real-time communication where both the client and the server can send messages independently at any time websockets offer a more efficient and responsive alternative to traditional polling techniques that's actually a really nice explanation one of the few times that chat GPT got it right for me but it's quite a lot to take in in one go so let's dig a little deeper and to start that Journey let's talk a little bit more about techniques for kind of near realtime communication that we might be more familiar with I'd like to talk about short polling now in short polling we have a client and a server and the client makes requests to the server on a periodic basis to ask for updates to see if there's any new information available and that starts with an HTTP request to the server uh asking for the data that it needs the server will then take that request go through the HTTP handshake negotiation grab the data if there is any and send it back and then we wait for an indeterminate amount of time until we kick off that process again and again and again and depending on how long that wait is in the middle we can kind of get to near real-time communication if we're making regular requests we're going to get that data more frequently and if you need an analogy to kind of really Hammer this point home you can think of this like you're about to kick off a 5-hour Journey with your kids in the back of the car and we all know what's going to happen 10 minutes in we're going to hear Rumblings from the back are we there yet are we there yet are we there yet for the remaining 4 hours and 50 minutes I think we can do better so this is what a websocket looks like again we still have the client and the server and everything still starts with an HTTP request it's just a slightly different type of HTTP request where the client asks the server to upgrade that to a websocket there's a slightly different handshake negotiation and assuming all of those things work out we have an open websocket and I like to think of that as a pipe between the client and the server that remains open for as long as either needs it the client is free to send data to the server as in when it needs to and the data is free to send uh sorry the server is free to send data back to the client as in when it needs it and to extend the analogy that we had with the kids in the back of the car we can perhaps think of this as the kids have now grown up and they know not to ask that question they're going to get that information as and when we have it available so let's take a look at what the HT or the websocket request actually looks like so it starts Life as a standard HTTP get request we have standard headers like the host name cookies anything that we want to send across or most things but we have a couple of headers that we're probably not used to seeing we have the upgrade header where we we're requesting a websocket connection the client is going to send a key to the server which the server is going to use uh in it's part of its handshake negotiation and we can send additional pieces of information such as the version of the websocket protocol that we're interested in using or any sub protocols that the server might have available for the client so the server is going to receive this it's going to make sure that it's from An Origin that it's expecting it to be from or it's happy for it to be from it's going to make sure that it has it can support the version of the websocket protocol that the client is asking for and assuming all those things work out we're going it's going to calculate a hash using that token that the client has sent across and it sends that back in an accept header uh which the client then uses to verify the request is correct and then all those things work out we have our open pipe we have a way to exchange data between uh client and server and what we end up with with an approach like this is reduced latency and increased efficiency so we're not having to wait between requests we're getting that data when we want it and we're increasing efficiency by not making multiple requests to our server and going through um expensive HTTP requests every time and so laral has as Taylor mentioned yesterday for the last eight years had support for broadcasting from the framework itself and with companion uh at the front and companion Echo we can kind of communicate with websockets but we wanted to kind of complete that package we wanted to add something that meant from your laral application you could have access to real-time communication without having to go elsewhere and so today I'm incredibly excited and proud to have the opportunity to show you a little bit more about laravel Reverb so what is Reverb well Taylor mentioned it yesterday it's a websocket server which you can run alongside your existing laral application it's an artisan command way PHP Artisan Reverb start and that's all you need to do and you can probably guess now from the fact that it's an artisen command that it's built with PHP it uses react php's event Loop under the hood to allow us to manage those real time sorry those longlived connections and it's built to scale now we're aware like most things in software that people's mileage out of pieces of software can vary depending on things like the amount of resource available on the server the number of connections we need to manage and the amount of data we're sharing between those connections and so we've worked really hard to try and make this work in for everybody so we've done stress testing with simulating different loads of traffic and then profiled those those uh applications to make sure that we have had the possibility to iron out any potential bottlenecks or memory leaks and we actually already have Reverb running on both Forge and Envoy and the server is not even breaking a sweat so we're pretty confident that Reverb is able to scale to meet the demand of even the most demanding of applications but if you do outgrow a single server setup one of the prerequisites when we built Reverb uh was to be able to allow it to horizontally scale so from the get-go you're able to uh deploy a fleet of Reverb servers which you sit behind a load balancer um which will distribute the connections between those servers and you can rest assured that Reverb is going to orchestrate all those connections to those that that Fleet of servers that you have on your behalf it's multitenant out the box so again I mentioned that we're already running it on Forge and Envoy what we're actually doing is we have have a brand new laral application running Reverb specifically for our websockets for our internal applications and so with a small configuration change within RB itself or within our laral application we're able to do that we're able to create different tenants and have uh Reverb manage those connections and keep the segregated from each other it's push a channels protocol compliance at the moment laravel's uh framework broadcasting capabilities are all kind of based around Around The Pusher channels protocol it's an open protocol that you can go and read about on The Pusher website and so excuse me and so with Reverb you're able to drop it into an existing application that you may already be using a uh broadcasting with a different provider and Reverb will just work there's no changes that you need to make and another nice thing about RB is the fact that you own everything so you're not having to worry about any sensitive data that you might be sending to any third parties you're going to own all that data and control the data that's going across your websocket server so we're going to go and have a look at Reverb in a bit more detail now but I just wanted to walk through the installation steps so the first thing that we have to do is install Reverb it's a composer require laral Reverb as Taylor mentioned yesterday this will actually become a two-step process when lar level is released because we won't have to enable broadcasting but at the moment you go into your app.php configuration and you uncomment the broadcast service provider class to enable broadcasting and then we install Echo lal's front-end companion for communicating with websockets and we're good to go okay so can everybody see that okay so this is what we're going to be working on now this is a new channel within my slide deck which is completely done I'm logged in on the left hand side is Taylor and I'm logged in on the right hand side of jez and what we want to do by the end of this session is to have the two communicating with each other it kind of works now but nothing real time is happening so I can go in as tailor and say hi and you'll see that we're using Live Wire it's calling the Live Wire update endpoint um so the message has been sent it's been stored in the database but nobody is seeing it until I go ahead and refresh the page so what we want to do is bring this to life and we're going to do three things today three are probably of the most arguably the most important things in slack we're going to obviously want to deal with the real-time messaging sending messages to each other in real time we're probably used to seeing typing indicators so I want to know when Taylor's typing so that I don't type over him and confuse the conversation and depending on whether you prefer a or whether your compan works asynchronously or synchronously you may not even like this feature or use it but we're going to talk about presence indicators so here I've got a list of all of the laral team members which are here at LaRon apologies if I missed anybody off I'm hoping I didn't um but they're all offline at the moment and we obviously know that both me and Taylor and Jess are all online so we're going to make that work just going to switch back here okay uh so I mentioned that lal's broadcasting capabilities work on the concept of channels which is quite nice when we're talking about channels in slack because there's a nice Synergy between the two so if we think about the Reverb channel here we probably need to make sure that people are authorized to access this channel so we're going to use a concept of a private Channel and a private channel is if you haven't used broadcasting before there's kind of an authentication process which has to happen before you're allowed to connect to the websocket so talk a look I'm not going to go too far into the details of how to wire that up that's all very well documented already but we'll talk a little bit about how that works in a minute and we can use private channel for the sending and receiving of messages and we can use the private channel for the typing indicator the idea being that people who can't access that channel won't be able to see those things happening the presence channel is a little bit more difficult because we need more information we need to know when we first connect to SL back who is currently online so we want to know that when we first connect to the websocket and we also need to know when people leave and when people join so that we can update that list accordingly so those are kind of the Three core things that we're going to look at over the next 15 or so minutes coner didn't get me enough water I blame the Maro blame the veggie M sorry that was a that was a bad slip of the tongue okay so that's what we're going to do let's go and look at some code so the first thing we want to do is jump into our editor I'm going to kill that and we want I'm going to kill that we want to start Reverb so I mentioned it's an artisan command we're going to do p HP Artisan Reverb start and I'm going to pass the debug option that's our server started that's all we need to do to have Reverb up and running in our application let's close that for a minute we'll come back and have a look then I mentioned we're going to use Echo to wire up the front end so in our bootstrap.js file this is typically where it happens it's in there at the moment commented out so you can just go ahead and uncomment this update your configuration and you have Echo instantiated we're going to add Echo to the window so that we can access it easily from our blade views okay so then we have a single live wi component which would mostly going to be working in yeah over the course of the talk and I mentioned we're using Live Wire what I didn't mention is I'm also using Vault and if you haven't used Vault I really recommend checking out it's a fabulous developer experience um and it's also really nice for presentations like this because I can show you everything without jumping around into different files so let's have a quick look at how this is structured uh we just have two pieces of State it's a pretty simple component we just have the channel that we're currently in and any messages which have been sent to that channel we we then have when the component mounts we're just going to grab the messages from the channel and we have a single action which is to send the message and all we're doing is calling a send method on the channel model and passing through the user and the message we'll look at that in a little bit more detail in a minute then we have some HTML or some Alpine and the only bit I really want to show you here is all that we're doing is iterating over the messages on the uh the yeah within the live wi component which we get access to for free because we're using Alpine and then we're going to jump down into the Alpine itself and we're going to have a quick look here so we have this channel object configured so all I'm doing is if you haven't or if you have used Alpine or haven't used Alpine there's an x uh data attribute that you put on your component and I'm passing this channel in so this is kind of maintaining all the state and giving me all the functionality that I need so I have few properties whether I'm currently typing whether any other users are currently typing the channel that we're currently connected to and then the more interesting part so in this listen for events that's where we're going to be doing most of the work so the first thing that we want to do is connect to the channel so we're going to use echo. private it's a private meth it's a the private function which will handle all of the uh authorization authentication and authorization behind the scenes um what actually happens is when you try to connect to a private Channel Echo will make a request to lal's broadcasting or endpoint and that will par through the currently logged in user and we'll pass back a Boolean as to whether the user should have access to that Channel or not so not a boole yeah we pass back a Boolean and if that boan is true Lara will go ahead and create uh an authentication token for us which we can then pass to the websocket server and the websocket server will verify that before allowing the user to um connect so we're now connected and if we go back to our browser and we look in the network Tab and we look in the response section F you can now see that stuff is starting to be pushed through our websocket uh so we the green arrows are messages that I'm sending to the server and the red arrows are messages which are coming back so I've send uh the Subscribe action or the Subscribe event and then Reverb is um communicating back to me that I've connected successfully but nothing still happens if Taylor were to type now we're still not doing anything real time so let's go and have a look at that um and the first thing I want to do is if you remember I had this action at the top that's responsible for sending the message well we're calling send on the channel model so let's go and have a look at what's happening in there pretty simple stuff we pass through the message we store the message in the database and then we dispatch this event message sent event and you'll notice that the message sent event implements the should broadcast interface and that basically tells laravel to anytime this event is fired I want you to broadcast that for me in this case broadcast it over Reverb we have a public property on here which is the message model and then all we have to do is tell Lara what channels we want to broadcast out on that can be one or that can be many in this case we're just going to broadcast it on a private Channel called channels. the Channel name and when this gets broadcasted this is all configurable but this is how it kind of works by default when this message is broadcasted you're going to get that any public property um on the event itself will be made available to you via Echo so with that event already being fired we know that's happening so let's go ahead and figure out how we might listen for it so we have our Channel our Echo Channel created and then we can just start chaining on methods so here I'm going to listen for the message sent event again this is configurable you can change all of these names but you know lal's got your back it's going to work by default with conventions so this message sent event is the same name as my event in the back end and all I do when I receive that is I'm going to pull uh the message off the event I receive and push it into the array of messages I have in state and so with a bit of luck let's try and make this a bit bigger jump back in here if Taylor now says hello we can see that message going across the websocket and Jess has received it in real time and if Jess replies with Su Taylor gets it too so with just a few lines of code we're already starting to be able to wire up this UI so let's jump into what the typing indicator looks like so in our text editor we have uh the editor itself is firing an event a JavaScript event on key down and we're going to use that to trigger our typing method so down a little bit further we have this typing method we're going to check there's a channel and then we're going to use this debouncer to make sure that we're not going to fire the start typing event every time somebody presses a button because that would be a little bit expensive and not useful we're going to debounce that send it the first time that they send a keystroke and when they don't send any more keystrokes for two seconds we're going to invoke the stop typing event pretty simple stuff what's interesting here is that we are using our Channel again but we're having we're seeing this new method called whisper and Whisper allows us to send an event name and um an object of data through but what's interesting about whisper is it doesn't communicate with the framework at all this just all happens in the context of the web we websocket server so our client will send the event that's going to hit Reverb reverb's going to say ah this is a client event I know what to do with this and it's going to broadcast it across all the users connected on that channel so we have the events firing now and if I were to jump back in my browser and show that I hope this is big enough sorry if it's not uh if I show tailor typing in here I don't see anything because I need I see just typing oh what have I done did I save I don't yeah I shouldn't need that yet let's try again okay maybe James is right once so when I start typing in here you see on J screen Taylor is typing and if Jess starts typing Taylor sees that Jess is typing and you can see the events firing back AC back and forth across the web socket okay so the last thing we're going to wire up is the presence indicator now I mentioned this is a bit different and we actually have a slightly different component for it we have a r users component this is just an Alpine component where we iterate overall of the users and the only thing that's interesting to see in here is that based on the user's online status we're going to change the color of the presence indicator so in here we're going to set some State using the JS directive which makes those users available to Alpine and then in the initialized function we're seeing some new Echo magic so echo. jooin is the function that's responsible for dealing with presence channels so it works in the same way presence channel is basically an extension of a private Channel but rather than uh when you connect to the sockets rather than just connecting you and telling you you're subscribed it gives you some information back and we can access that information with the hear method so when I join the workspace channel here it's going to go ahead and authorize me that I'm able to do that and then I get this into this hear method where I get past the currently online users that Rab's going to to provide us and I'm calling a mark online method which basically just iterates over the users and changes their online status I also have this joining function which allows us to uh gives us a user every time somebody new connects to the websocket or to that particular Channel and the leaving is the inverse of that so we're going to mark them as offline uh when they disconnect and so again with just those few lines of code we can jump back into our browser and we can immediately see that uh Jess myself and Taylor are all online and just to prove that this works I'm going to jump into a new tab close the old Tab and Taylor's Now offline and I jump back in and Taylor's now back online again so you can see that with the tools that we have available to us in the laral ecosystem we can build up these really really uh engaging Snappy uis but there's one more thing I want to show you so if I jump back in the network Tab and I send a message as Taylor hello we've already seen that I have this Live Wire request that I'm making I'm making an HTTP request every time I send a message and if you're in a busy if you've got a busy slack installation um that those requests are going to start to build up and become expensive and we already have this open web socket for which we can pass data between client and server so is there any reason why we can't use that well currently yes because nothing is connected to our laral application we're using a third party of some description to handle websockets for us but the fact that Reverb is running in an Artis and command alongside a laral application opens up some interesting opportunities every time Reverb receives a message it's going to fire off a message received event and we can hook into that as we would do with any other laral event so I have a listener here called broadcast message and you can see that it's listening for laral Revo events message received event we get the message which has been passed through we can do some manipulation on that and make sure that we are um getting the right event that we're interested in and then we have the channel pass through as well as part of that event so we can grab the channel from the database obviously we would have some more uh protection in place not just grab one and hope that it's there um but we can if we've got the channel we can then call the send method as we're already doing and we know that that's going to dispatch an event to broadcast that message across to all connected users so if we jump back into our Reverb component and we jump down here to this send method you can see at the moment that I'm just invoking the Live Wire action to send that message for me and and this is a little bit gnarly at the moment we don't have wrappers around this at the moment I just wanted to show you what we can do now that we have this opportunity um because we are implementing the um Pusher channels protocol we can use The Pusher SDK under the hood which is why I'm grabbing The Pusher um object directly from Echo and I can call the send event method and pass through an event name some data that I want to pass across the channel and the channel name and so now that's no longer going to send that request to laravel that's going to send that request to reverb which is also laravel it's kind of confusing um but that will fire off the message received event which we're now hooking into with our broadcast message event and we've basically implemented the same functionality so if I now jump back in here let's grab this network tab again yep we're connected to all the channels if Taylor now says uh I don't know what does Taylor say uh pretty good you you can see that my send message event has gone across and that's worked its way through reeva Rea fired off that event it eventually made its way back to the message sent event and that's been broadcasted to all the connected users so with this approach we've been able to take away an additional HTTP HTTP hop that we didn't [Applause] need okay wh let's jump back to General and we'll let everyone know we're back well thanks team uh that's what I wanted oh but there's one more thing as we like to do laral we want to make these things really easy for you to use so when we ship Reverb there's going to be a seamless integration with Forge and Taylor showed the app panel on the screen yesterday which James has been working on and we keep adding to that and making it better and so Forge will have uh its own entry for Reverb in the applications panel it be a toggle switch you give it the host that you want to run it on and it's going to go ahead and configure your enginex host it's going to tweak some settings on the server to make it Optimal Performance for Reverb and of course you want to be able to see how your websocket server is performing so we're going to ship Reverb with a pulse card which will give you a realtime indication of the number of connections you're managing and the number of messages that are being sent across the channel and I'm really really thankful that Tim and Jess built this because I started working on reverb I don't know let's say 18 months ago and this didn't exist and this was the single thing biggest thing that I was worried about solving and they solved it for me in that time okay so that's really all I've got aside from a short summary about what we've learned today and probably the biggest takeaway that we can all have is that objectively slack is better than teams and we've also learned that websockets are a better approach to listening to your kids screaming at you in the back of the car and we've taken a really deep dive into Reverb and how it can work along the alongside the other tools in the laral ecosystem to help you build really engaging Snappy and efficient real-time user interfaces that's me check it out go smash some emojis I can't do acrobatics what I can't do acrobatics I have questions so first question is from Michael he's asking can rever Marmite yeah tell me about it yeah can Reverb be used without Live Wire yeah sorry yeah there was just for the benefit of the talk I built the slide deck the slide deck in Live Wire because it was a really nice way to show you how it works but it can work with any yeah well obviously it works with laravel and then any front end stack that you're using you can pull in Echo and everything just works great awesome so from you probably know this guy Mr Luke Downing oh no the parrot guy I'm still upset he didn't give me a baking train you need to ask his wife yeah true he's asking with Reverb uh will be will Reverb Library running along your side laral app how do you need a separate app for that you can use either so I think I don't know what's going to happen but my gut feeling is that most applications will probably run it alongside their existing application but for instance I mentioned that we already with Forge and Envoy are running a completely separate installation and have those connect to that server it's because we want to not put extra load on our existing servers great oh no you know is it who is it the next way user yeah that guy so from the anonymous user will you ever ever eat again veite absolutely not I can still tell tast it it was really bad timing for you to give that to me then sorry I didn't know that was happening by the way no no not at all so big Applause and thank you for Reverb thank you
Info
Channel: Laracon EU
Views: 5,240
Rating: undefined out of 5
Keywords: laracon, laravel, php, laraconeu, laravel reverb, reverb
Id: yrL5eCMpqtc
Channel Id: undefined
Length: 33min 42sec (2022 seconds)
Published: Thu Mar 28 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.