Making A Lightning Web App: Part 3
Lightning Fast UI with Web Sockets
Hey, this is part 3 of a 5 part series on building a Lightning app. If you haven't read part 1, you can go here and start from the beginning.
Our app as we left it is now a fully functionaly Lightning web app, but it's far from the polished result we're aiming for. It relies on polling the server for updates, and makes the page refresh when we make a post. So we're going to speed things up by replacing some of our traditional calls with Web Sockets.
Web Sockets and Lightning make a great pair, as the ability to make small and frequent payments needs small and frequent messages to be sent back and forth between the client and the server. If you're not familiar with how sockets work, I suggest doing a little light reading before we get started. But don't worry, the concept is extremely simple once you take a look, and I'll try to explain along the way.
Getting Started: Clone the (new) Project
Yet again, we'll start with cloning a further iteration of the project. If you want to keep any changes you made to the first part, feel free to manually add the new code.
git clone blah blah
Also yet again, you'll need to install the dependencies we need. We didn't add too many this go-around, but adding web sockets to our API has necessitated a few more:
Alrighty, now we can get into the code!
We haven't added any new files here, we've just altered some of the previous ones to use sockets instead. Let's start with the server, shall we?
We've added a new websocket endpoint here using the
express-ws module. Unlike GET, POST, PUT, or DELETE requests that return information once as a part of an HTTP request, websocket endpoints open a persistent connection to the server that allow us to pass data back and forth. In this case though, we'll only be passing information down to the client, and otherwise using HTTP requests for everything else.
The first thing we do is grab all of our existing posts, and feed them through the socket. Each post is sent as a "message" of JSON encoded data. We then setup an event listener for new posts, and when they're made, we send a message as they come in. This'll make our application update in real time!
The final bits are just websocket house-keeping. We ping the client every 10 seconds just to keep the connection going (Some servers or clients cut off connections if they don't hear from them for a while.) And once we see the connection is closed, we'll stop sending posts to it.
And that's it for our server! Onto the client:
We've now made our App component the central store of post data, so that our other components can be much simpler, and just take in data as props. As soon as it mounts, it'll open our websocket connection and start listening for posts. It saves them to component state, and passes them to the
PostForm components as props. If there are any errors in the connection, we can save that too and display an error message along with a button to call the connect method again.
Posts component is now so simple that it's only a render function, our
PostsForm component has been changed a bit to handle our new socket data:
We've replaced our previous methodology of polling to server to see if our post has been accepted. Now we watch for our component updating due to new props being passed, and see if the post that's currently pending is in the list of posts that have been made. If it is, we just reset the form to its initial state so that the user can start posting again immediately.
And that's it for our code overview! There were a few other improvements here that I didn't explicitly cover, but you should check out all of the components and play around a bit yourself to see what you can do.
Up next: We'll be integrating WebLN into our app to allow for a slicker payment experience, as well as message signatures for our posts.