 So we're going to talk a little bit about building real-time applications in Ember. First, a moment or two to introduce myself. Hi, I'm Steve. I am an instructor at the Turing School of Software and Design out in Denver, Colorado. We are a not-for-profit, seven-month intensive developer training program. If you're interested in mentoring young aspiring developers, please come talk to me after this. I also have t-shirts, so if you like t-shirts, also. Please come talk to me after this. So we teach Ruby, we teach Rails, we teach JavaScript, and most importantly, we teach Ember. So even if you're just getting started with Ember, you know more than somebody's been doing it for a day or two. And I really advocate for how much you will learn, how much your skills will level up working with aspiring developers. Also, if you're interested in hiring junior developers, also talk to me. I got junior developers for you. So I have been working with Ember for about 18 months. It's incredible how much has changed. Decision to choose Ember as a framework that I wanted to learn came like most things in my life through exhaustive, laborious, comprehensive research, as you can see here. You can see I did get a favorite from an Angular news site. And that should be of no surprise if you've ever tweeted anything with the word JavaScript in it, then you're probably familiar with that. I did initially only get one response, seemed like some good advice. And I got to say, I followed that advice, and I definitely believe it was the right choice. For me, there are, somebody else did respond later on, saying, do you even need a JavaScript framework? But we'll just ignore that. There's always somebody. So really, there's three major considerations when choosing a framework to work with. The first is the merits of the technology itself. That is one of the three. The other two are the core team's priorities and aesthetic. Does it jive with my own? In this case, I definitely believe that's true. And finally, the community. It's the community awesome. And I think from the keynote on forward yesterday, we've seen that all three of these are, I think, really solidly in Ember's favor. So I'm very excited to be working with Ember. So we're going to talk a little bit about building real-time applications in Ember. Ember is a framework for building ambitious web apps. And I am of the philosophy that real-time applications definitely fall under the category of ambitious. So on one hand, this is a story about web sockets. On the other hand, it's not just a story about web sockets. It's a story about any kind of browser functionality that you want to integrate into your application. It's a story about web sockets as much as it's a story about geolocation, as much as a story about user sessions, as much as it's a story about the web audio API. It's also a story about working with third-party libraries that weren't expressly written with Ember in mind. So in this case, web sockets are going to be our hero in the telling of the story. So we should probably address, make sure we're all on the same page with what a web socket actually is. I think that's a really good question. And luckily, it has a very straightforward answer. Web sockets are HTTP-independent bidirectional TCP-based protocol over port 80 standardized in 2011 by the IETFS RFC 6455. But you already all knew that. It didn't need me to tell you. More specifically, the traditional way that we work with web applications is through the request-response cycle. We make a request. The server does whatever those server-side people do. We get a response. We then work with that response. The problem is, is that if stuff happens and changes on the server, the server doesn't have any way to tell us, theoretically. It has to wait for another request and then it can send us the new information. Some websites handle this by polling every five, 10 seconds and trying to make believe their real-time applications. A web socket is more like a two-way tube across the internet where the server can send messages when it has new things to tell the client and then the client can then respond to those messages. So what a web socket is used for? Collaboration on documents, analytics dashboards. I think Luke mentioned yesterday, it can be really useful if your app is actually out of date and changed. And you want to prompt the user to bring in a new version of the application. You can send that message over a web socket. In this case, I think that the hello world of real-time applications is the chat or instant messaging application. So we're going to build one of those together today. First, just a quick demo of web sockets in action. Here we've got a live Twitter feed. It's taken from the streaming Twitter API. And as it hits the server, a web socket pushes that tweet up to Ember, which does its thing and brings it into the model and updates the application accordingly. So if you want to say, like, hi, mom, and have it on the screen, now's the time. Hello world. Cool. So the other thing about some of this fancy client-side technology is, can we actually use it? Is this some kind of Chrome canary Firefox nightly thing? Or is this widespread available? My user comes to the site, and I have some of the web sockets. Are they going to be able to take advantage of that? The answer is for the most part, yeah, with my apologies to the Opera Mini user. But I think they're used to it at this point. In the event, we have a little red in some earlier versions of the Android browser, a little bit of red in some earlier versions of Internet Explorer. If you do need to target these older browsers, you're not actually out of luck. There's a lot of libraries that will actually give you some backwards compatibility. These libraries are also really great, because they will give you fallbacks if you can't make a solid web socket connection. They'll fall back to long polling. They'll fall back to flash sockets if they need to. Socket.io is a library for Node. Fe is actually a library for both Node as well as rack-based Ruby applications. But this is not like language or ecosystem-specific. Whatever your server-side language or choices, there is a library that supports that. I've also heard that Rails 5 is going to support it, but I don't know. Cool. So now that we are experts on WebSock, because we can all go update our resumes, we're going to endorse each other. Let's actually go forward and begin to implement these. This is ultimately what we're going to build by the end of our first iteration. It's a very simple chat application. You put in your name, you put in any name, because anonymity on the internet is awesome. You put in your name, you put in a message, theoretically somebody else does the same thing. It pushes to your application. This is a brief sample of what we're going to start with with some boilerplate, other than style sheets and things. This is a very lonely chat room right now. As you can see, there's no WebSock that's involved. The only thing you can do in this chat room right now is talk to yourself. Which is what I feel like I do on Twitter most of the time, so it's not much different. So we're actually going to begin to add to this a little bit. But before we can do that, this is not a talk on server side WebSockets, don't worry. We do need a server that's going to push those WebSockets to our client so we can actually react and deal with them. So we're going to start with a very simple WebSocket server. It's 14 lines. Again, any language you want, any framework you want, it's cool. I did it in Node because I made the assumption that we're all familiar with the JavaScript programming language. And here it is. So what we'll do is we'll acquire the WebSocket library, we'll start up our server at port 8080. On any new connection, we'll bind an event that when a message comes in from that connection, we will broadcast that message. What does it mean to broadcast that message? Well, it means that we're going to take all of the connected clients and we're going to send it to them, to their client over the WebSocket. So what does this traditionally look like on the client? Like, how do people normally work with WebSockets? I took a look at the Socket.io documentation and just grabbed their hello world for a client on the client side. It's pretty straightforward. You can see we're going to do some down traversal. We're going to grab some stuff from an input. We're going to get the value of it. We're going to append a list item to what I believe is another element that's a UL. This is fine in this example. It's okay. However, we've seen where this goes. We've seen where this road leads. This road leads to a term that I stole from Eric Brent, called selector-based programming, which is less and less like you're developing an application and more and more like you're running around the DOM, like trying to update stuff and move stuff around and append stuff and remove stuff to give the illusion that you have a Web application. We can do better. One of the things I love about Ember is that it allows me to build my application. And then the DOM becomes a representation of the state of my application. I don't have to run around and do all these hijinks. I don't have to do that. So we're going to try two or three different approaches here. The first is we use a standalone controller. And we're just going to start that with Ember Generate Controller WebSocket. And this is going to give us a new file called AppControllersWebSocket. In here, we'll talk through the code. This is probably going to be the densest piece of code we look at all day. Or not all day, like in this half hour. We're going to start out with an array of, we've looked at some pretty intense code today. We're going to start out with this list of callbacks, this list of subscribed functions that we want to call on every message. And what we'll do is we'll expose ourselves a subscribe function that will put something, that will register a callback. And we'll also have an unsubscribed function that will deregister the callback. In here, we'll simply make a connection to our server. When a message comes in, we'll parse that message and we'll call all the registered callbacks that we did with subscribe and unsubscribe. We'll also give ourselves a nice abstraction to send a message. So in our chat room, let's actually get some other people in here. What we'll do is we'll say that we need this new WebSocket controller. We'll say we rely on it. And it'll actually make it available to us under controllers.websocket, which we're going to use a computed alias to give ourselves a cleaner interface too. Then what we can do is we can implement a subscribe where we'll actually have a, we need to name this function so that we can deregister it later. So we'll have a function that receives a message, which will simply take the message and pop it on to our model which starts out as an empty array. We will then use the WebSocket controller and subscribe our new function. We will also do the same thing on our way out of that controller. We'll clean up after ourselves. And finally, when a message gets submitted, we will actually send it to the server over a WebSocket. Lastly, we've wired everything up. We just need to turn stuff on and turn stuff off. We only have one control in this application, but this would be useful if we had more than one controller. We'll simply on our way in on the chat room route, we'll call that subscribe method on the chat room controller. And on our way out, we will again clean up after ourselves. So let's see that in action. It's true, it's cute. I will do. Cool, so we can see that I'm getting trolled remotely. And so the system works. This approach is great, as you can see it works. Somewhat limited, right? Right now it works between controllers. What happens if we wanna have the stuff in a component? What happens if we want to bring our WebSocket into our models? Right now this approach isn't well suited for that. The best thing about being in an amazing community is that you share these struggles together, right? You're not the only one that feels some of this pain. Tom actually made a proposal about 11 months ago for something called services, which would be kind of a way to bring this functionality in other places in your application. So let's actually refactor our code. We'll refactor it to take it out of this standalone controller and we'll move it into a service. A very similar approach will go Ember Generate Service WebSocket. That'll give us two files in Ember 0-1-15. I've heard from Robert Jackson that in 0.2 you will not get that second file, which we'll talk about cause it's here and then we won't use. What it does is it takes our service and it injects it. In this case it's injecting it into every route. And so this service would be available in every route. If we wanted it available in every controller, you can do that. You want it available in just the chatroom controller, you can do that as well. We're not gonna do any of that. Ember 0-1-10 gives us a new syntax for bringing it in that I think is cleaner and a little more declarative. So how do we refactor this controller into a service? That's it. We just inherit, now it's a, we just moved it to this new file that we generated and we inherit from Ember Object instead. We'll get rid of that controller. We don't need it anymore. And then we do need to update our chatroom controller. So we're gonna take out this logic that relies on our standalone controller and we're going to instead, WebSocket is gonna be Ember Inject Service. The eagle-eyed among you might notice that I didn't actually have to pass in a service there. What Ember will do in 1.10 will look at the name of the property and say, hey, to find the WebSocket property you probably want the WebSocket service. If I named this property sandwich, then I would have to be a little bit more explicit. That's also a terrible idea. And that's it. We've now refactored our standalone controller into a service. So let's go, right now we have a very vanilla WebSocket implementation. I'm thinking we pull in a third-party library, right, for the laws and we'll kind of take advantage of some of the things that has to offer. Point of interest, Socket.io has both a client-side library and a server-side library. We're gonna use the server-side library on the server, client-side library on the client, and they'll separate them out. So we'll actually refactor our server to be, to use Socket.io on the server-side. You can see I took my 14-line WebSocket server. It is now nine lines, if you wanna be like that. Six lines, effectively. I can, Socket.io gives us lots of things like chat rooms or rooms and channels and a whole bunch of different options as well as like events for connection and disconnection. Here's just an example of different events that you can kind of bind to. We'll also install that on the client. This is just solely the client-side library. And what we'll do is, in our Brock file, we will import that into our build process. So when we build our application, it's included. Finally, so you don't actually need to make a whole bunch of changes to your service if you didn't need to, bring in this library. You're simply now gonna have, bringing in this Socket.io client library exposes an IO global that you can just kind of use. I'm gonna show you kind of a stripped-down service with the hope that if you're not interested, you don't have a burning desire in your heart right now to make a real-time application. Maybe you're more interested in geolocation. Should be like the bare minimum so you can see what that would look like. So here we're simply exposing the WebSocket connection that we've made on a knit. And we're actually gonna keep that sugary send method as well to send stuff back over the socket. Okay, so let's go into, let's look at some of the things that we could do with this new setup. We could bind to all sorts of different events. We could have if somebody connects, disconnects if they press the party button. Cause every app needs a party button, am I right? So we're gonna try one more thing in our time together. Just more, isn't there? So we're gonna play a game called what is your favorite JavaScript feature? Our options are Nan does not equal Nan. Semi-colons as a whole. Double equals that the type of Nan is a number. ES4 or Rails. And if you're interested, you can play along at home by going to bit.ly slash jspol and should you conference Wi-Fi permitting, you should be able to cast your vote. I'm about to, this is my favorite right here. Away for some connections. Or you can play with this for a little bit. Big Rails fans in here. Awesome. So thank you very much. The code for the chat room is online. You can harass me on Twitter or GitHub. You can email me and you can hire our students. Thank you.