Building Real-time Applications with Socket.io


  1. Socket.io Basics Introduction Hello, my name is Patrick Schroeder, and welcome back to Building Real-time Applications with Socket.io. In this section we'll discuss the basics of what Socket.io is, and how it is used within the Node.js framework. This will include an overview of how Socket.io is built using WebSockets, along with one of the most important features that are shipped with Socket.io. Next, we'll take a look at what companies are currently using Socket.io in their production applications. And finally, we'll discuss a variety of possible use cases for the inclusion of Socket.io in your next application.

  2. Socket.io Framework Let's take a minute here to understand what Socket.io is, as well as where it comes from. Socket.io is a JavaScript-based framework that is built and maintained as a Node.js module. There is a heavily-starred GitHub repo that provides us with information on how to set up and use Socket.io. Examples are given on how to set it up with both Express and Koa. You can also find a list of Socket.io methods with descriptions on how to use each one of them. There is also a website which is located at Socket.io. Here you can find a few demos by clicking on the Demos link, which includes a link to the source code for each demo project. If we click here on the Docs link, we can see an area for the Server API and for the Client API. One of the best features of Socket.io is that it provides us with the same API methods that we can use for both the server, as well as the client. There is also a Slack channel that boasts an active community, as well as a blog to keep us current on the newest changes. Socket.io was not built from the ground up, instead it is based on the WebSockets technology, so let's now learn a little bit more about WebSockets, and how we can use the browser to power connected clients.

  3. Built with Websockets Socket.io uses the WebSocket technology as its base for real-time updates, so let's now discuss how Socket.io is derived from this WebSocket technology, what problems does Socket.io solve, and what are some of the key features Socket.io supports? Socket.io is built with Engine.io, which is an abstraction on top of the WebSockets technology, and WebSockets is a browser-based technology that was standardized for all major browsers in 2011. The WebSocket technology allows for direct two-way connections between the client and the server. This makes it easy to build real-time apps, because the server can dynamically push new data to connected clients whenever there is new data, or the state has changed. WebSockets, just like Socket.io, relies on an initial handshake between the client and the server, and once this handshake is made, data can then be freely exchanged. Socket.io was developed for two main reasons. The first was to create a simplified wrapper for creating and working with WebSocket connections. This is similar to the idea of jQuery being a simplified DOM wrapper around JavaScript. And the second reason was to eliminate some of the connection problems that naturally occurred when working with WebSockets. The solutions provided by Socket.io include built-in fallbacks for old browsers that don't support WebSockets, an AJAX long polling fallback that accounts for sites where WebSockets is turned off, and other solutions for issues that occur with missing events, and these include events such as heartbeats, timeouts, and disconnections. One of the biggest benefits of using WebSockets, and in turn Socket.io, is in its ability to scale. Sockets are joined using a single TCP connection. Normally, communication between client and server occurs with multiple HTTP requests being made every time a piece of data is retrieved or needs to be updated, but this is not the case when using WebSockets. Since the connection is left open, any updates or changes are sent directly, and this leads to a huge savings in both latency and performance. Another huge benefit of using Socket.io is that it comes with excellent cross-browser and device support, so you can expect the same speed and performance across all platforms, browsers, and connected devices, and this is based on the fact that connections are initiated and maintained within the browser window. Here is a chart from the website caniuse.com, which shows all the browsers that currently support WebSockets. Currently, 87% of the world is able to use WebSockets natively, and by using Socket.io, we're able to close the gap even more, which creates solutions for working with older browsers like IE 8 and IE 9.

  4. Socket.io Features Let's now discuss what Socket.io actually does. Socket.io enables real-time, bi-directional, event-based communication. This means that users can connect to a socket. Once connected they can then send or receive data to all other connected sockets in real-time. Communication is event-based, and this means that we'll be subscribing to events, and then be able to receive any changes as they occur. You can think of this as a free-flowing stream of data between connected devices. Once the device connects to a stream using a handshake, the connection is left open so that the server can pass and receive data from any and all clients in real-time. The format that Socket.io uses to pass data back and forth is in the form for JSON. JSON stands for JavaScript Object Notation, and will look something like this, consisting of a key value pair inside of a curly bracket. As we progress through the course, you will see examples of how we can listen for, receive, and respond to events using the same methods on both the client and the server. Socket.io is optimized to work best with low latency operations. This includes uses like sending messages and pushing out data. Examples might include chat applications like Slack, real-time analytics like Google Analytics, and sending notifications that you might see in places like Twitter and Facebook. As of Socket.io version 1.0, there is also the ability to send an image, audio, and video as a binary stream. However, we won't be dealing with this feature in this course since it's not supported by enough browsers and can be unstable.

  5. Socket.io Uses There are many real-world examples of companies using real-time technologies as part of their products. A number of these are using Socket.io to power their applications. A few examples given on the Socket.io website include products like Microsoft Office, Yammer, Zendesk, and Trello. These specific use cases are focused on the ability to update documents, offer client support, and provide a chat interface. However, there are also many other uses that we can think of that currently employ or benefit from real-time updates. For example, the real-time notifications you receive when using Facebook or Twitter can be distributed using WebSockets. You can create real-time dashboards that get updated to show user data like you might see in Google Analytics. Another example is any other kind of application that can connect users across the globe, this includes multi-player games, updating scores for sporting events, gambling applications that update the amount of wages won or lost, trading applications that offer real-time updates to changes in the prices of stocks, and real-time forms for collaborative editing between groups in different locations.

  6. Summary In this module we learned that Socket.io is a framework that is built for Node.js, and maintained as an npm module. We discussed how Socket.io is an abstraction on top of WebSockets, and how it is used to solve a number of limitations inherent when working with WebSockets directly. We learned that when connecting to a socket, it requires just an initial handshake, then the connection is left open for data to be sent and received. We learned how Socket.io uses JSON consisting of key value pairs to transmit data. This type of data is best suited to work with Socket.io as it represents low latency operations that are small and easy to transmit through a browser. Finally, we looked at a number of products currently using Socket.io, as well as other possible use cases. A few of these included sending notifications, updating scores for sporting events, and real-time collaborative editing.

  7. Installing Socket.io Introduction Welcome back to Building Real-time Applications with Socket.io. In this module we'll work on two small projects to get you familiar with installing Socket.io and working with JSON data. In the first project we'll work through how to install and set up Socket.io in our local environment. We'll start off by creating a simple Node.js server using Express, then we'll require in Socket.io, and add it to both our server and client files. Once our setup is all complete, we'll print messages to our Node console and to our browser console in order to demonstrate how they are connected. In our second project, we will build an app that will track and display changes in the price of bitcoins using the Bitcoin China API. The starter code for these projects can be found here at the Socket.io Demos repository.

  8. Socket.io Setup Let's now set up our first project using Socket.io. We'll be building a simple app to demonstrate how to create a Socket.io connection between the client and the server, and then print out messages to both the browser console and the Node console. I'm using Sublime Text as my preferred text editor for these projects, but you're welcome to use any editor that you're most familiar with. I've created a folder and named it starter. You can place this folder wherever you'd like. I'm going to navigate over to the location of this folder in my terminal and then type the command npm init. I'm going to hit Enter a few times, but you can put anything you'd like for these values. The npm init command creates for us a package.json file that we can then use to download and save npm modules. I'm going to finish creating our starter template here in my terminal by typing the command touch app.js, which creates an app.js file, then I'll create a public folder by typing mkdir public. I'm going to navigate into this folder by using cd public, and create a new file here by typing touch, and then index.html. Let's switch over now to Sublime Text to see our new folder structure. And we can see here that there's an app.js file, along with a public folder which includes our index.html file. I'm now going to require in the modules that we'll need for this project. So back in my terminal I'll cd back into the root, and next I'm going to include express, path, and socket.io by using the command npm install, along with the --save flag. Let's switch back into our editor. Once these modules are finished downloading, we should see a new folder that gets created called node_modules, and this includes the modules that we just downloaded from npm. The first thing that we'll do is open up the index.html file and create a simple scaffold. I can use the html:5 command, which uses the Emmet Sublime Text plugin for this. One pretty unusual aspect of Socket.io is that we can include it directly into our HTML file like this, referencing a file location that doesn't seem to exist, and the reason we're able to do that is because the socket.io.js file gets automatically exposed by the Socket.io server. We can dig into this a little bit more by navigating into our Socket.io Node module. So we'll open up socket.io, then node_modules to locate a socket.io-client folder. So we'll open that up and here we see a socket.io.js file, and this is what we're actually referencing within our index.html. And if we open up the README file and scroll down a bit, we can see a How to use area that explains how we're able to use Socket.io on the client side. So let's finish up our initial scaffolding of our starter app by setting up our server files. We'll go back into our app.js file and start off by requiring in our node module dependencies, express and path. We'll then set up a variable app to expose express, and I'm going to set up a server by requiring in http, and then passing in our app variable into the http server. When requiring in socket.io, we need to pass the server as a parameter. I found this to be the simplest way of setting up a Socket.io project. Let's now make a connection to our public folder by using the express.static method, and passing in path.join. And we'll also make a variable for our port number. And lastly let's test this out by listening to our server, passing in the port variable, and a function that will print a message when we run the file. So everything looks good and our server has started. In the next video we'll create our first socket connection.

  9. First Connection With our setup in place, let's create our first connection. We'll do so by opening up our app.js file, and opening up connections using our io variable declared up above. We can use the on method provided to us by socket.io, and then specify an event known as connection. This connection string is part of the Socket.io library and does the job of opening up connections between the client and the server. We've added a socket argument here that's going to be used every time we want to send and receive messages. Let's also add a log message letting us know a new connection has been made. Now, let's set up the connection to our client. So we'll open up our index.html file, and it's very easy to initiate the connection, also known as a handshake, between our client and server. All we need to do is set a variable for our socket, and pass in our server location. And we do this inside of a script tag. We'll restart our server, and notice that we get listening on port 8080. Now if we navigate to this port in our browser, we should expect to get our new connection made message in the console. And if we open up another window, and navigate to our localhost, we'll get a new message indicating another new user has been connected. And that's all that we need to do to get Socket.io up and running.

  10. Send and Receive Messages With our connection in place, let's now see how we can send and receive messages from the server to the client, and vice versa. We use the emit and on methods as our primary method for handling events in Socket.io. So inside of the connection event, I'll say socket.emit, and then pass a string event listener, along with a JSON object that will send a greeting message from the server. This string called message-from-server will be used on the client to display our message. And we'll also set up an on event listener that will listen for messages coming from the event named message-from-client. So we'll do the reverse on the client, and emit a message that can be picked up and displayed as a log message in our Node console. Let's switch over to our index.html file and set up our events on the client. When using Socket.io, we're able to use the same methods for both the client and the server, so I can say socket.on, and listen for the event, message-from-server, then I can declare a callback function with an event parameter that contains the JSON message hello client from server. In order to display the message in our browser, I'm going to use some vanilla JavaScript here and print the message. Let's also set up our emit event, which was called message-from-client. We'll send back a similar message to the server containing the string message, Hello from Client. Notice that when sending messages, we're doing so with an object, and when receiving messages, we're using a function that has a parameter that contains the message that we received. Now let's test this out, and to do that I'll switch back into my terminal and restart the server. And since we're sending and receiving messages within our connection event, we're going to see both messages displayed immediately. And here we can see our two messages sent from the browser to the server, and vice versa.

  11. The Pub/Sub Pattern Now that we've seen Socket.io in action, let's take a brief moment to discuss the programming paradigm that we're using, and that is the publish/subscribe pattern, also known as the Pub/Sub pattern. At its most basic definition, the Pub/Sub pattern is a one-way messaging, events-driven manner of writing code. Essentially we have a set of subscribers that register their interest in receiving a specific category of messages, while the publisher produces messages that are then distributed across all the relevant subscribers. What makes Pub/Sub perfect for our uses is that the publisher does not need to know who the recipients are in advance. This creates a loosely coupled relationship between the publisher and the subscribers, and since the publisher doesn't need to know anything about the individual connections, this can help to create an ideal pattern for distributed systems that are able to evolve and scale. You've already seen this pattern in action. Here we are subscribing to the event message-from-client, and here we are publishing a message to all those subscribed to the event called message-from-client. We'll continue using this pattern in all future examples for every time we're sending and receiving bits of data.

  12. Introduction to Bitcoin App Welcome back to the second mini project of this module, building a bitcoin tracker application. In this project we will build an app to track the changes in bitcoin currency using the Bitcoin China API. We'll be using jQuery and Bootstrap within an HTML page to display the buy and sell prices of bitcoins in real-time. This application will help us to better understand the format of the data being sent to the view, and how to compose the streaming data into a readable table.

  13. Bitcoin App Scaffold Let's begin this project by taking a look at the API we'll be using, which can be found here at btcc.com/apidocs. This site provides us with a number of different APIs to access. Let's click on the one that says WebSocket. This API is set up to work with Socket.io, so that all we need to do is require in Socket.io, and then set our socket to the btcc.com API URL. Then we're able to subscribe to any one of these markets. After subscribing we can then listen for a ticker, which will be giving us JSON objects in real-time that look similar to this example. Switching back over to Sublime Text, I've opened up a folder called btcApp, and this folder can be found as part of your resource's files, as well as here on GitHub. This folder contains the beginning code we'll need for this project. So let's open up the starter code and see what's inside. We'll start with an app.js file that has a basic Express server set up to use Socket.io. We're serving up a view from the public folder using the express.static method, and in our node_modules folder you can see that we've already added express, path, as well as socket.io. In our HTML file we've included a style reference to Bootstrap via cdn, then I've created a header area to display the market along with highs and lows, and then below that we'll display a Recent Trades, inside there we'll show both the buy and sell price, along with the trade volume. We'll be using jQuery to assist in displaying the data into our defined IDs, and then at the bottom here I've made sure to include socket.io's script. With that covered let's take a look at what our starting app looks like. We'll navigate into the location of my project in my terminal, and start the server by typing node, and then app.js. Navigating over to localhost:8080, we can see how our sample app will look before any data is added.

  14. Bitcoin App Build Let's now hook up to the Bitcoin API so that we can start streaming in some data. First, we'll open up our index.html file and scroll to the bottom. I'm going to include a script tag and set up a socket that connects to the Bitcoin China API. Next, I'm going to subscribe to one of their data points called marketdata_cnybtc. I need to create a connection to the socket, and this can be done using the on method. Then inside of the connection I can listen for a ticker event, and each time an event happens we'll be passed a JSON object, and the JSON object that we get back would be stored here in this data argument. We'll also include a log message here so that we can take a look at the object we're being passed inside of our browser console. I'll navigate now into my project location in the terminal and type the command node app.js. When we go to our localhost:8080 and open up the console, we can see objects start appearing. If we open one up, we can see it looks just like what we would expect as given to us within the API docs. Let's now add our jQuery using this data argument to populate the bitcoin data into our HTML. We'll start by adding the name of the market to the ID we created called market, (Working) and we define this up above in our code. Now, let's create the jQuery code to populate the high and low areas found here. I will use the ID of high-count, and the data.ticker.high value, and then I'll do the same for the low-count and add in data.ticker.low value. I'm going to copy over this format and just change the values around. First, for the buy price, and next for the sell price, and finally for the volume amount. And these will end up being displayed here and here. And now, with everything in place, let's restart our server and refresh our browser. You might have to wait a few seconds for the first object to come through, and once it does, we can see the buy and sell prices along with the volume being updated in real time.

  15. Summary In this module we learned how to install Socket.io and send messages between the client and the server. We created a simple Express.js server to handle our server-side connections, then we added a script tag in our HTML to reference Socket.io. We opened up communications between client and server using the string event known as connection. We then discussed the Pub/Sub pattern of writing code and how the events-driven nature of this pattern is ideal when using Socket.io. We also looked at different ways of sending and receiving JSON style data. The two small projects that we worked on have taught us the basics of Socket.io, and prepared us for the main demo project, which we'll build in the next module.

  16. Chat Application Introduction Hello, my name is Patrick Schroeder, and welcome back to Building Real-time Applications with Socket.io. So far you've learned the essentials of working with Socket.io, and built a few basic starter apps along the way. In this section, we'll build out a working chat application; we'll be using Angular version 1.5 as our front-end framework of choice. Our chat application will include a login page where users are prompted to submit a username. Once inside the main page, users will be able to send messages that will be received by all connected users in real-time. Users will also be able to click a button to send likes to the user of their choice, and this will display a message to only the selected user. In addition to the files added to the lectures, you can also find the starter files along with the completed project in the GitHub repo.

  17. Starter Files Explained For this project, I've provided you with a starting template that includes boilerplate code that can be found in the chat_before folder in the GitHub repo, and also included in the lecture downloads. So let's open up these files now and understand the structure. In our root folder we have a package.json file, and this includes our three node packages we'll need for this project. Our server.js file acts as the main entry point for our application. In here we have the same setup as before, first requiring in our modules, then locating our public folder, then initiating socket.io, and finally, listening for our server to start. I've included a bower.json file, and this will install all of our front-end libraries. We're adding a few Angular dependencies which will be discussed when we get to our Angular implementation, along with Bootstrap for styling, and Font Awesome so we can add in some icons. We have a bowerrc file here, and this will tell Bower where to install our declared dependencies. In this case, we'll be installing them in the bower_components folder inside of our public folder. So now let's inspect what's inside of our public folder. We'll start with the index.html file. This file serves as the main entry point to our front-end application. At the top here we add in our CSS files, then we make sure to Bootstrap our Angular application by declaring ng-app. Below that we create a navbar area that is shown on every page, and we insert ng-view here, which tells Angular to load our defined routes and partials. Next up we make sure to include socket.io file, just like we did in our previous set ups. And finally, we declare our Bower JavaScript files, along with our Angular JavaScript files. Let's now open up our app.js file. This file will serve as our Angular module loader for our five dependencies, as well as configuring our two routes. We'll have a join route and a main route, with their associated controllers, and I'd like to set html5Mode to true, which will remove the hash sign from our URL. I've included a join folder and a main folder, following the convention of separating out our application components by feature. These folders both contain an HTML file, as well as a controller file which we'll dig into as we build our app. Our css folder contains a style sheet with a few style declarations for our divs and body. We also have a components folder, which contains the skeleton of a socket factory we'll use to connect to our Socket.io client. And finally, we have a bower_components folder, which contains all of our front-end libraries. And now that we have a better understanding of our file structure, let's get to work building our chat application.

  18. Add Join Controller Now that we've taken a look at our boilerplate files, I've renamed our folder to chat, to make it clear which project we're working on. I'm going to be using nodemon in this project, which will automatically restart our server any time changes are made to our server-side files. You can install nodemon globally by going into your terminal and using the command npm install -g, for global, followed by nodemon. And if you're on a Mac you may need to prefix npm install with the command sudo. Once nodemon is installed, navigate to the location of your project and type nodemon server.js to start the server. We'll navigate over to localhost:8080 and load up our app, which at this point just displays a non-functioning join page. To get started building our app, let's make this Join button work and take us into the main page. We'll open up our join.html file and inspect the contents. In here we're greeted with a form that has an ng-submit called join, and an ng-model called name. Let's now use these model and property declarations in our controller. To do so, we'll open up our join.Ctrl file. You'll notice that I've provided you with my preferred set up for creating controllers. We start with an IIFE, or immediately invoked function, to create a container around our variables, we declare our module as app, and we give a name to our controller. Then I use $inject to inject the dependencies I intend to use. Inside of my join controller function I'm going to declare a few variables. We're using an ng-model called name to store the user's name in the form, so we'll set that equal to an empty string. I'm also going to declare a variable here called nickname to use below. Now let's create the join method declared in the template. To do this I'm going to set scope.join to a function, and inside the function I'm going to store a reference to scope.name to our nickname variable to be used later. I'm going to be using localStorage to store the name of our user, and after the user submits the form I'm going to send them to our main page by setting the location.path to main. With our join controller set, let's run the server now and see what we get. Now we're inside the main page, but it's still static, and our messaging isn't functional just yet. So the one simple thing that I want to do here is display our user's name next to this welcome message, so to do that let's open up our main.Ctrl file, and our main.html file. At the top of our main.html file, I've created a place for Angular data binding called mynickname. So flipping back into our main controller, I can do this by setting scope.mynickname to localStorage.nickname. We can now test this out in our app and see that the username gets displayed in the main page. And with our username set, let's start adding some Socket.io methods to display all of the connected users.

  19. Join Event At this point we've created a way to store our username locally, now let's see how we can connect that username to a socket, and then broadcast our username to all other connected users. If we open up our main.html file, there is an area here called Other Users, and this is where we'll be displaying the names of all other connected users. But before we get there, we need to create a socket service to handle the business logic of sending and receiving events through Socket.io. We'll be doing this in our socket.Srvc file, which is located in the components folder. So far I've created a skeleton similar to what's found in our controller file, and created a factory named socket. And we need to use rootScope here because Angular 1 does not intercept WebSocket data coming from the browser. I'll start by defining a socket variable, which is equal to the io.connect method, and this will open up Socket.io connections between the browser and the server. We're going to be adding two methods here called on and emit, they're going to be functions, so I need to return these as an object to make them public. The on method is going to listen for all incoming events for a given name, and then issue a callback performing some action. And then the emit method will send socket events out to our server to be received. The method will include optional parameters including some data, as well as a callback. Now let's use our newly created service to emit our username in the join controller. So opening up the join.Ctrl file, I've already added the dependency for our socket factory right here. Within the join function I can say socket.emit, then declare my event name, which will be join, and include an object to be sent along. In this case I'm going to send back my nickname, which will end up being whatever the user has inputted in our join form. So let's now create the on method in the server.js file that will receive this emitted join event. So switching into my server file, the first thing that I'm going to do is create a user's variable that will store an array of users that have joined our chat. Inside the connection handler is where I will define my join event, so we'll say socket.on, our join event happens, then passing in a callback function, and I'm going to create a couple of log messages here so we can see what's going on in our terminal. Now I'm going to create a reference to my socket, and I can do this by saying socket., and then a variable name to reference, which I'm going to set to nickname, and this is going to equal data.nickname, so if a user joins with the name John, then this will be the socket name. Now in order to track the users, I need to set users of socket.nickname to the join socket, and this will become clear when we log out this user's object. Next, I'm going to create an object to be pushed into my users array that will contain my user's nickname, as well as a unique socket ID. So I'll create my user object, which has two properties, a nickname, which will be set to data.nickname, and a socket ID. So this socketid is something which is automatically created and attached to every new instance of a socket object. Then I'm going to push this object into my users array. And finally I'm going to emit a new event called all-users, and send with it my array of users. Notice that in this case we're using io.emit, instead of just socket.emit, and the reason is because we need to broadcast this event to all of our connected users. To understand the inner workings of our socket object a little better, let's add a few users and observe these logs.

  20. Socket Object I've opened up a couple of windows and navigated to port 8080, and have my server running. I'm going to create a couple of new users named me and me2. Now let's go back into our Node console to observe the output. Scrolling up to the top, you can see that we've logged out our data, which is nickname set to me and me2, and this represents our first console log declared here. And next we've logged an array of users. We're only seeing one user here since this log is declared before adding the user called me2, but we can see that the socket has been given a nickname that we declared as the user's name, which is me, and then we get this big object defining our socket, so if we scroll down little bit, we can see that there is an id key which is set to a unique string, and this is what we've defined as our socketid identifier in the object up above. Everything else below contains data that is used within the browser for handling WebSocket objects. Okay cool. Now we've seen the actual contents of our socket object, let's now see how to display all our connected users within our main page.

  21. Show All Users We can display all the users that have joined by using a socket.on event listener in our main controller. So opening up our main controller file, I first add a reference to our users that we're going to display as an empty array, and I'm also going to create a variable reference for the mynickname property to be used below. To listen for our all-users event, I can say socket.on, passing in all-users, and a callback function containing the data I'm getting back from the server. I'll create a log message here, and now I want to filter for the other users, so I'll set my user scope to filter the data, and then return the users that are not equal to our newly joined user's nickname. And now we're ready to test out our new event handler. I'll open up two new windows here, and log in first as me, and then as me2. So when adding two new users, you can see that it's working when a new user joins, so that's pretty sweet, but we're not seeing the original user show up in our new user's column. What's happening here is the server is firing the all-users event before it's getting registered in the client. So one way to fix this is to emit an event at the top of our controller to get all of our users. So we'll say socket.emit, and our event will be called get-users, and we're not passing in anything, we're just triggering the event. So let's now flip over to our server.js file and create our corresponding event. So when the server would listen for the event by saying socket.on, passing in get-users, as well as a function that will then emit the event all-users, and passing along our users array. Also notice that in this instance we're using the socket.emit, since we don't want to broadcast to all listeners, but only to the socket that made the initial request. So let's test this out one more time. And look, now we're getting all the other users populated into our view automatically when we join as a new user. Okay great, we've made some nice progress, now let's get into the meat of our chat application and set up our messaging.

  22. Send Messages We're now ready to set up our messaging feature. The only new concept in this section will be how to broadcast our messages to all connected listeners. Let's start out by opening up our main.html file, and about halfway down we see a column that includes a form with a sendMessage function, and we're also binding to a message property here. Then below, we're going to loop through and display all the messages that have been sent and received inside this well area here. Now we'll open up the main controller file, and start by defining an initial state for our message, which will be an empty string, and also a variable for all of the messages, which will be an array. Let's now define our send message function. I'm going to send along an object with my emit event, so I'll declare my object right here, which will contain the message itself, along with who sent the message. Now let's go ahead and add the socket event, which will emit an event called send-message, and also pass along the object that we just defined. Then we'll go ahead and clear the message from our form, and then push this message into the view. Let's now switch over to our server file and create our corresponding event. So we'll say socket.on, then declare our send-message event, along with the function that has a data parameter that holds the object that we received. And now we're going to broadcast, or send back to all connected users our message object, and to do this we'll say socket.broadcast.emit, and then name our event, which will be called message-received, and then pass along the data. The socket.broadcast method is going to pass the data to everyone except the socket that sent the event. And since we're emitting a new event, we naturally need a corresponding on event to pick it up. So switching back into our main controller, we'll create this message event right here, and we're just using the data we received back from the server, and pushing it into our messages array. So let's now fire up our app and see our messaging system in action. Okay great, it's working. We're seeing instant messaging broadcast among all connected clients. Now we do have one alternative when broadcasting messages. Instead of limiting our messages to all other users, we can include ourself. So just like how we're using io.emit up above, we can use it in place of socket.broadcast. So if instead we say io.emit, sending over the same event and message, then in the controller we won't need to push our message to the view after sending. So we can simply comment out this line, restart our app, and the app is going to work in just the same way.

  23. Send Private Likes We're making great progress with our app. Let's take the next step and learn how to isolate our messages to the user of our choice. In our app, next to every user is a thumbs up icon. When clicking on this icon, I want only that user to receive a special message. So let's first open up our HTML file, here is where we're displaying the other users, and next to the user's name we have our icon, with a click event called sendLike, then below that is where we're displaying our likes column, and this includes a thumbs up icon, the name of the user who sent the like, and a text message. Switching now into our main controller, I'll first create an empty array to store the likes. Now let's create our sendLike function. So we'll start with scope.sendLike equals a function that accepts a parameter that represents the user object that I want to like. This user is an object that has a nickname, as well as a unique socket ID. Remember, we defined this object right here when the user first joined. I'm going to add a log message here to print out our user, and I still need to create a reference to just the socket ID of the user, so I'll make a variable for the user's ID, and then I'm going to use the super handy get method from lodash, passing in the user object, and then declaring which key I want to grab. Then I'm going to make an object to send out to our server, which is going to contain the nickname of the user who sent the like, along with this ID representing who we want to send the like to. Then we'll emit an event called send-like, containing our object, and to make this a little more clear, let's open up our browser and output this log message. So you can see when clicking on another user's like button, we get their object and then we're grabbing this socketid in our ID variable. So with that set up, let's now wire up our back-end event. Opening up our server file, we'll start by creating a corresponding socket event which is named send-like, and then of course passing along a function that contains the data that we received. And we'll go ahead and log out that data to our console. Now we want to send part of this data to a specific socket, and we can do this using the to method. So we'll say socket.broadcast.to, and then specify our socket ID, which is data.like. So now we're specifying who we want to send the data to, but we still have to actually send them the data, and socket.io again makes this very easy because we can chain along an emit method, and then create our event name, which we'll set to user-liked, passing along the same data object, then all we need to do is create this corresponding event in our controller. So we'll say socket.on, passing in our newly created user-liked event, along with the function containing our data. So we'll go ahead and log out the data, and then push to our likes array data.from, again representing the user that sent the like, and now we can test this out. And you can see everything works as expected. Also, make sure to observe the logs in both our browser and Node console if you're confused by any of the code.

  24. Disconnect Along with a connection event, Socket.io also provides us with a disconnect event, so right now, if a user closes their browser window, it's not going to register that this user has left our app. So let's fix that now by taking advantage of the disconnect event trigger. In my server file I'm going to create a new socket event that will listen for any socket disconnections, and in order to remove the disconnected user I just need to filter out the user from my users array, and then I can emit my all-users event to all sockets, and pass along the newly formed users array. Let's test this out by creating some new users, and then we'll remove a couple, and now we can see how everything gets updated correctly.

  25. Socket Join Method We've been able to build a neat little chat application using just a few methods. Now there's just one other method that I want to show you, and that is the join method. When using the join method, we're able to subscribe our socket to a given channel, so within our on event, we can create a namespace for that socket, and in this case we've named it private. By using this method, we can form group chat and private rooms. In order to demonstrate how this works, I'm just going to create a few buttons with click events. So at the bottom of our main.html file, I've added a button that when clicked, will have our user join a private room, and then below that we'll have a button that when clicked will emit a message to only those users that have joined the private room. Moving over to our main controller, I'll start off by defining the logic for our joinPrivate function, and when the button is clicked we'll be joining a private socket and sending along our user's nickname. And we'll just log a message here, private room joined. Now let's go ahead and add the corresponding on event in our server. So we'll say socket.on, name our event join-private, and then pass a function containing the data. And here is where we'll have our socket join a room, which we'll name as private. I'll also add a log message here to show in our terminal. Now we'll go back into our controller and create the function for our other click event called groupPm. When a user clicks on this button, we'll emit an event called private-chat, and we'll pass along the message hello everybody, to be seen by any other socket that has also joined. Then in the server we'll set up our socket.on private-chat, passing along a function containing the message, and then we can broadcast the message to all users using the broadcast.to method, then just pass in the name of the room that we set up right here. We can chain our emit event to send back to our view an event that we'll name show-message, and of course include the data object that contains our message. Switching now back into our controller, we can then show off the message by registering our show-message event, and in this case I'm just going to log the message out to our console. Now that we've got everything set up, let's see how this works in our browser. First I'll join three new users to our chat, then I'm going to join this private chat with just the me and me1 user, then I can click on the Send Group PM button, and only user me1 is going to receive the message. And we can see in this case by opening up the console in me2 and seeing that there is no message being displayed.

  26. Summary In this module we built a functioning chat application, and in the process covered the most commonly used methods within Socket.io. We started with the on and emit methods that act as a communication hub between the client and the server. We then added the broadcast method, which acts to send our data to all connected clients. Then, we looked at how to send events to specific sockets by using the to method. After that we discussed how to use the join method to create namespaces for our sockets. And finally, we used the disconnect event to help us listen for socket disconnections, and to update our users array accordingly.

  27. Course Summary In this course we covered the most important features, benefits, and uses of Socket.io. I really enjoyed putting this course together, and I hope you feel like you're a better developer for taking the time to view it. Remember that the uses for Socket.io are certainly not limited to chat, but can be integrated with many other real-time applications and database structures. Please know that I am available to answer any questions you have in the discussion area. Thank you so much for watching, and I'll see you in the next one.