Check out a free preview of the full Complete Intro to Real-Time course
The "Coding a HTTP/2 Push Backend" Lesson is part of the full, Complete Intro to Real-Time course featured in this preview video. Here's what you'd learn in this lesson:
Brian adds a stream event listener to the Node server. If the correct endpoint is requested, the connection is established with the client and the chat messages will be sent. The connection will remain open until the client has disconnected.
Transcript from the "Coding a HTTP/2 Push Backend" Lesson
[00:00:00]
>> We are now into the exercise part of this particular course of HTTP2. So here's the one CLI thing that you have to do for me during the course of this course, course of this course. I'm gonna delete these so that I can regenerate them for you and you can see.
[00:00:26]
Delete. So let me bring this up. Let me make it bigger. Maybe not quite that big, maybe that. Okay, so we're gonna go into the HTTP2 portion of this. And we're gonna go into exercise. Okay, so HTTP2, well, it's not necessarily built into the spec that you must do it over HTTPS.
[00:00:56]
It actually is required by all the browsers. There's no browser that supports HTTP2 over non-SSL connections. So in other words, even though we're doing local development, we have to have a certificate, right? So you and I just need to generate a quick OpenSSL certificate. I left a bunch of instructions on the course website.
[00:01:21]
I'm gonna do it here for Mac so you can actually see me do it with Mac. The same thing would work for Linux. If you need to do it via Windows, your best bet is to do it over Chocolatey, so you can use Chocolatey to install OpenSSL. But kind of after that, you're on your own, because I don't really generate too many certificates on Windows these days.
[00:01:41]
So if you have Homebrew installed, if you don't, go to brew.sh. I have a link there in the course notes. But otherwise, you just do brew install openssl. I think really any version of this will work. I already have installed, let's clear. Then I want you to go to the root directory of your project.
[00:02:02]
So you can see here, I'm in this directory, so the exercise directory. And I want you to run two commands, and I'm just gonna copy and paste them cuz they're long. And I don't really understand what they do, if we're being totally honest with each other. So course notes, where's my course notes?
[00:02:25]
Intro to Realtime. I actually have it in the files, too. If you come here to back and server, I have them here. These are the two commands that you have to run. I'll actually just copy them from here. But yeah, they're in the course notes. They're here into chat with HTTP2.
[00:02:47]
These two things right here are the ones we're gonna have to run. So you have to copy the first one. One of them generates a key, and then one takes the key and generates a certificate. Okay, so I'm gonna paste the first one. It's gonna ask you a bunch of things.
[00:03:14]
It doesn't really matter cuz we don't really care about these certs. Okay, as you can see here, I took this very seriously with the responses that I sent. Again, it does not matter, okay? And then you're gonna take this second one here, and you're gonna generate a cert with the keys that you generate.
[00:04:01]
Okay, and now you can see I have three files here, csr.pam, key.pam, and server.crt. So unfortunately, it won't work if you don't do these. We have to do this over SSL or the HTTP2 part of this just won't work. Okay, the other thing I wanna make sure that I call out is we've been doing our localhost here.
[00:04:35]
Make sure that when you're coming back here to your browser, it has to be https://. This s is critical or else, your server will not connect. So that's another thing to keep in mind. Okay, so now that I've generated these, I actually installed them for you. So as long as they're in the correct place and named the correct things.
[00:04:59]
So if you run these two commands in the correct place, which is in the root directory, not the backend directory, everything will just plug in and work for you. And let's go take a bit of a tour of our code here. So at this point, you should be able to say npm run dev.
[00:05:19]
It should work. So this should look really familiar. Try to keep things as similar as possible as they were from the previous section. Couple of things here, we're no longer using Express. You can make Express work with HTTP2. What I'm showing you is possible with Express. But I wanted to get lower level so you can really understand what's going on underneath the hood.
[00:05:46]
HTTP2, this is the actual direct standard library from Node.js. It's not a module. It's a module built into Node itself. fs is for file system, path is a helper for doing paths. These are all from Node itself, same with URL. serve-handler, this is actually a library put up by Vercel for serving static assets.
[00:06:07]
It's very easy to use. If you've ever done npm install serve, this is the middleware that handles everything inside of serve, just so you know. And then nanobuffer, we've seen that before. This is all stuff you've seen before. This is us starting the server, and this is us creating the secure server with the cert and the key right there, right?
[00:06:33]
So that all goes there. We're about to write some code that goes here. So server on request. So we check the path, and if the path is not something going to our endpoint, I'm gonna assume it's a static asset, which is what this does right here. Otherwise, if it's a post, then we're assuming that a user is posting to the endpoints.
[00:07:03]
And this is actually just reading something out of the post. And then down here, we'll handle the posts. But you remember what body parser was doing for us in Express? This is what body parser does for you. It reads stuff out of a request, and then makes a buffer out of it, and then it parses that to JSON.
[00:07:25]
Didn't make you write it cuz it didn't feel important to the course today. But in case you're wondering, that's what it does for you. All right, so that's it for the server so far. Right here, we're listening to requests, which is like a full on normal 1.1 style request.
[00:07:46]
That's what all this is gonna do. But we're about to listen for something called streams. There's no built-in router to the HTTP library. That's what Express does for you. It's basically a router on top of HTTP. So that's how we have to handle the path and method stuff here.
[00:08:07]
Because that's what Express would normally do for you. I'm excited about this. This is one of my favorite things to just mess around with. I really enjoy going in and finding these low level of abstractions and seeing what stuff is gonna do for us. We're gonna do it with WebSockets too, it's wild.
[00:08:27]
Or I don't know if it's wild, maybe I just have a weird definition of what is wild and what is not. Anyway, this is not therapy hour. I'll talk to my therapist about that later. Okay, so we're gonna say, server, which is our Node server, right? Whenever it gets a stream request, which is specific to HTTP2, we're gonna run this handler.
[00:08:52]
This does not need to be async. Okay, so it's not an async. It could be async, but it doesn't need to be. So it's gonna take in a stream and a headers array. Okay, so the first thing is everything is gonna both make a request and open a stream as well.
[00:09:12]
So when someone requests styles.css, this is gonna fire, and then this is gonna fire, right? So we have to just make sure that we're paying attention to the correct things. So first thing we do, I mean, basically just copy this. We're gonna make sure that we're only paying attention to the correct path and method.
[00:09:36]
So again, yeah, streams open for every request from the browser. And we're gonna say, if path === /msgs. Yeah, sorry, I probably should explain this earlier, but this weird triple equal signs here I have, it's actually just my font combining those into one glyph. But it is actually, you can see that's now a double equals, and then a triple equals.
[00:10:12]
And method === GET. So basically, wait for the msgs and GET to come in. The first thing that we wanna do is we wanna immediately reply with 200 OK and the encoding, right? So it might be helpful here if we just say connected. So this will just let you know that it connected a stream, so something like that.
[00:10:49]
And you can even here, you can say plus, stream.id, this can be a little confusing because Node will reuse IDs. So you'll have three connected and they'll have different IDs, but then one of them will drop out and then Node will reuse that with a different user. So just be aware that you might see the same ID be reused.
[00:11:13]
Then you can say stream.respond. Immediately, you just wanna say, I received your request. Everything is healthy. We're about to start responding back to you. So :status 200 to let them know that it's a 200 response. And then we're just gonna tell them how we're gonna send data back.
[00:11:37]
Now you might be tempted to put here application/json, which is actually not totally true. Cuz we're gonna be sending them multiple packets of JSON, which if you put those all together as one thing would not actually be valid JSON, right? I can't have multiple objects. There's no way to stream JSON.
[00:11:58]
That's actually one of the problems with JSON as a protocol for communicating is it doesn't stream very well at all. Whereas unfortunately, something like YAML, which YAML sucks, but it does stream fairly well. Anyway, so we're just gonna say text/plain, and that'll just tell whoever is consuming this is like, make no assumption.
[00:12:18]
I'm gonna send you a free form data, basically. And then we just tell that it is charset=utf-8, just to let it know how it's encoded. Okay, so that's gonna establish the connection and then keep it open. And then we're gonna write the first response. We're gonna first say stream.write JSON.stringify.
[00:12:49]
Cuz again, Express isn't doing all of the nice, packaging it up for us. So we have to stringify it ourselves. I'm gonna say msg getMsgs. And then here, we're gonna say stream.on close. So whenever the user disconnects, We just wanna log that out and say, console.log disconnected. + stream.id.
[00:13:38]
Okay. So you can see here this is running. If you go over here, nothing's happening. So this might terrify some of you, potential security risk ahead. I promise you I'm not exfiltrating your Bitcoins or something like that. Though honestly, great idea, I should have thought of that earlier.
[00:13:57]
[LAUGH] This is fine. The browsers just don't trust self-signed certificates. So you have to click here on Advanced and accept the risk and continue. It'll look similar in Chrome, and Safari, and Edge, but just say accept it. What's happening here? What did I do? Req is not defined.
[00:14:26]
Yeah, what did I do here? Rec headers, so here on 39 and 40, just delete, it's just headers. So on 30 and 39, headers is not coming from req as it was down here, right? It's actually just coming in as an array. So yeah, line 39 and line 40, headers path and method.
[00:14:53]
Refresh that, try again, there you go. Now our Chat With Me is back up. Again, nothing is working and nothing streaming, but we'll get there here in just a second. One thing that I did add for this particular section here in the top right, see this little red dot?
[00:15:10]
I wanted you to be able to visualize, am I connected to the server or am I not? So we're gonna write a little code to just modify that so that if I'm connected, it'll be green and if it's disconnected, it's red. You can see right now I'm not connected to the server, so it's gonna be red.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops