Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
The first step in using sockets is to set up a connection. In this video we will see how to both create the connection, and implement our own communication protocol between the clients and server.
[? Music ?]
0:00
[Code/Racer] [Creating the Socket Connection]
0:02
With just a couple of lines of code, we were able to get
0:05
Socket.io both installed and listening on our server,
0:07
and we were able to see that we’re able to retrieve the client js file,
0:11
and we actually connected using the developer’s tools.
0:15
The next step is to actually start writing some code.
0:18
Now, we don’t want to just do this inside of our console.
0:21
We actually want to create a JavaScript file for our application, or at least our testing page.
0:23
Later on we’re going to be integrating something called Spine.js,
0:27
which will be a client-side application framework that will manage a lot of our JavaScript code.
0:30
But for now, we'll just use a normal JavaScript or CoffeeScript file
0:35
that we'll just experiment with to see how we can get
0:39
connections going back and forth over our sockets.
0:42
What I want to do is create an application.js,
0:46
but actually I am really comfortable in CoffeeScript right now,
0:50
so what I want to do is actually be able to write
0:53
a client JavaScript file in CoffeeScript and have it
0:56
compile over our application.
0:59
Now, Express is really an extension to something called "Connect,"
1:01
and Connect is a way of writing servers with middleware,
1:05
and we've seen different middleware like our less here,
1:07
which manages how we serve our CSS file, which is actually backed
1:10
by a less file.
1:14
And another middleware is our express.static.
1:16
And we can use another one that's included
1:19
that's called "express.compilers," and this is actually
1:22
part of Connect, but Express serves it out of its own directory as well,
1:25
so we could have included Connect and called connect.status,
1:29
but Express will provide it through its own middleware.
1:33
We're going to use a middleware called the "Compiler,"
1:37
and this will allow us to compile a few different things, but most notably,
1:40
we can compile CoffeeScripts into JavaScripts.
1:43
We'll do "app.use," and we'll do "express.compiler."
1:45
And now we need to pass it some options.
1:52
Basically what we need to do is we're going to pass it an object
1:54
with a source attribute, and this is going to be
1:57
where we're going to be serving it out of, and we're going to
2:00
store our files out of the public directory, so we'll do "__dirname"
2:04
for our current dirname "/public."
2:09
And we could also put a destination, but by default,
2:12
it's going to rewrite a JavaScript file in the same place that
2:15
the CoffeeScript file was found.
2:18
And all we need to do now is pass it the enable,
2:21
and this is an array of what type of compilers
2:25
we want to support, and the name of the compiler we want to add
2:29
is "coffeescript," all one word there.
2:32
Now what we should be able to do is in a public directory, we have this app.js.
2:36
I'm going to remove that one, and let's create a new one,
2:40
and we'll call it "application.coffee."
2:44
Now, we're going to name it application.coffee,
2:49
but since we have the compiler middleware, if we request
2:51
application.js, it should compile the coffee
2:54
into js and serve that.
2:57
Let's test it out, and let's just do a simple alert,
3:00
passing hello, and this will very quickly tell us
3:03
if we have our application up and running.
3:06
The next step is to add that into our layout.eco file.
3:10
We'll create another script,
3:14
and this should be served out as "/application.js."
3:18
And if we close the script tag, save it,
3:24
and our server should have restarted, so if we go back here,
3:27
if everything is working, we should get an alert.
3:30
And we're getting a 404 Not Found, so let's take a look and see
3:33
if everything is working right.
3:37
I'm going to go ahead and just stop the server really quick.
3:39
It doesn't look like it restarted, but maybe I forgot
3:41
to actually save our server.coffee, so let's double check and go back.
3:44
We have one there,
3:48
and it looks like we've got a couple of starts there,
3:51
so hopefully everything is up and running.
3:53
Again, if we refresh, we just got this message popping up
3:56
saying "Hello," so now our CoffeeScript file is being compiled
4:00
into a JavaScript file.
4:04
Let's go back and make sure it's really working.
4:07
If we go back in here, we can see there's now an application.js,
4:10
so this is what got compiled.
4:13
This is our CoffeeScript compiled into JavaScript.
4:15
Let's go back to our Coffee.
4:18
We're only ever going to worry about this.
4:20
And let's do "Hello World."
4:22
If we refresh, we've still got "Hello" showing up,
4:26
so let's try that again.
4:32
As many times as we save it, we still get "Hello" instead of "Hello World."
4:34
Let's double check and make sure everything is working.
4:38
But I think we have a little error.
4:40
We certainly do.
4:43
Now, why is this happening?
4:45
Well, let's take a look at our application because it really matters
4:47
how we define our middleware.
4:50
We're back here in our server.coffee,
4:53
and the way middleware works is every time it gets a request,
4:56
Express or Connect is going to pass the request
5:00
through every piece of middleware we have.
5:03
And if that middleware is able to accept it,
5:05
it will serve whatever it needs to serve.
5:08
Otherwise it will pass it on.
5:10
For instance, when we go to /,
5:12
instead of just going to this application get handler here,
5:14
it checks with express.static.
5:17
Can you handle /? No.
5:19
And then it goes to this one. Can you handle /?
5:21
And it can only handle application.css, so it passes on.
5:24
Then it goes to the compiler and says can you handle just this /?
5:28
And since there's nothing in the directory that we gave it that would handle it,
5:31
it passes it on, so up to the router here,
5:35
where the router says hey, I've got something for /.
5:38
I'm going to return it.
5:41
So every time we go through a request, it goes through all of our middleware
5:43
in the order we defined it, so the first thing it goes through is express.static,
5:47
and then our less, and then compiler, and there are a few middleware
5:52
that we don't see in here, but that's the idea of it.
5:55
What's happening is what the compiler does is when it gets a request,
5:59
it checks inside this public directory to see if there's an application.coffee
6:02
that it could compile to the js, and it did,
6:06
and it saved it into our public directory.
6:09
But when we do our next request, what happens?
6:11
Well, the first thing it hits is express.static,
6:14
and it says can you find an application.js?
6:17
And it can, so the express.static
6:20
returns right away because there's already an application.js stored in it.
6:24
What we would need to have happen is have our static be checked
6:29
after our compiler because we always want the compiler
6:32
to handle it whenever available.
6:35
Because it's already stored in there, the express.static is just going to say
6:37
I already have a version.
6:40
Even though our application.coffee is there and the compiler could create a newer version,
6:42
the static just stops the request right there and says I already have a file
6:46
on the disk that I can send.
6:49
No need to go any further, so one way we can switch this around--
6:51
and we'll just pull the express.static line
6:54
and put it last, and this has another opportunity too.
6:57
If we had an application.css file in our public directory,
7:01
if static came first, it would serve that file.
7:05
But since now it comes last, application.css
7:08
will always be handled by less.
7:10
You want your static to come pretty low if you have some things
7:12
that are going to be handled by something more dynamic
7:15
like our less middleware or our compiler.
7:17
If we save it out and we refresh,
7:20
we get a Hello World, and everything works out just great.
7:24
So now how do we communicate back and forth between our client and server?
7:28
Let's take a look right now.
7:33
The way we can do this is we'll open up our application.coffee here,
7:35
and we're going to store a variable into a variable called "socket."
7:40
And this will be done by taking io.connect and calling it with no arguments.
7:45
If our server was in a different place, we could pass in
7:50
a URL to where we want to connect to, but by default,
7:53
it will do our local host on a port that we are currently on, which is what we want,
7:55
our local host 3000.
8:00
We have our socket here, and now in our socket,
8:02
we can listen for events, and events are how we're going to communicate back and forth.
8:06
We'll create different event names for different types of things
8:11
that are going to happen, and they will go in both directions.
8:14
Let's say we have an event that's going to be coming from the server
8:17
to the client called "server-update."
8:20
We can say our "socket.on," and this first takes the name of an event
8:23
we're going to listen for that's going to come from our server,
8:29
and we can arbitrarily call it "server-update."
8:32
It doesn't matter what we call it, and so that's our event name.
8:36
And the next argument is a handler function, and the handler function
8:40
is going to pass in some arbitrary data that will come along with that event,
8:43
and we'll just say that it's going to pass a message.
8:47
Again, this is what we're defining, and what we're going to do
8:51
is on the server side create a complementary piece of code
8:54
that will actually send a server update with a message.
8:57
What do we want to do when we get a server update?
9:01
Well, we can do "console.log."
9:03
"We have an update."
9:06
And then we can do another console.log of "message,"
9:12
so we have that saved out.
9:16
So now what we want to do is figure out how we're going to
9:18
receive that connection from the server.
9:21
Remember, we stored an IO connection here from when we listened to our app.
9:24
This has a sockets object on it that can also listen
9:29
to incoming connections.
9:33
Underneath where I defined my routes here,
9:35
I'm going to call "io.sockets," and this represents
9:38
all of our sockets, because the server is listening for
9:42
sockets of any browser to come in,
9:45
so the first thing we're going to look for is a connection.
9:48
Because the client will initiate a connection by calling .connect,
9:50
we need to be listening for new connections, so an event is going to be called,
9:54
so we can listen for that event.
9:58
And that event is called "connection,"
10:00
and this is an actual event, so it does matter what we call it.
10:04
This is not something that we define.
10:07
This is something that socket.io provides us.
10:09
And what this event provides us in the callback function
10:12
we're about to define here is it will pass in the actual connection,
10:15
or I like to call it the socket.
10:19
This is the individual socket that's coming in from a browser.
10:21
If 10 browsers connect, this callback function is going to be called
10:25
10 different times, each time with a different connection
10:28
to a different browser in our socket variable,
10:31
and this is where we can set up our actual information
10:34
sending stuff back and forth.
10:37
So what can we do?
10:39
Well, now that we have this socket inside of this callback function,
10:41
we could call something like "socket.emit,"
10:43
and this is the complement to the on method.
10:47
On listens for events, and emit sends them.
10:50
We'll remember that in our application.coffee,
10:53
we're listening for an event called server-update,
10:56
so we can do "socket.emit 'server-update.'"
10:59
And these are the only 2 things that have to match up,
11:04
and anything after the first argument, which is the name of our event,
11:06
we can have as parameters, and remember,
11:10
the parameter that server-update has is a message,
11:13
so we can say, "Here is a message from the server."
11:15
Now, these could be things like objects, numbers,
11:24
or any other thing that could be easily turned into
11:26
a JavaScript object notation or a basic object.
11:29
But we know strings are easy to send,
11:33
so what we have here is as soon as a client tries to connect,
11:35
io.sockets is going to call its connection and pass us
11:38
that reference to that socket representing that 1 client.
11:41
And as soon as we get that, we're going to call emit,
11:44
sending a server-update message with a string.
11:47
And on our client side, here is the connect call that will trigger it,
11:50
and we're calling "socket.on," and we'll see "server-update,"
11:53
so when we receive that message, we're going to take it in,
11:58
do a couple of console.logs, and now we can see the server
12:00
being able to send a message to the client.
12:03
Let's refresh.
12:06
And when we refreshed, we see it immediately says we have an update,
12:10
and here is a message from the server.
12:13
Now, that's great, but that's pretty much just like in normal requests.
12:15
We made a request, and the server immediately sent something back.
12:19
But what we could do is we could actually postpone that message whenever we want.
12:22
Instead of immediately calling "socket.emit,"
12:25
I'm going to call "setTimeout."
12:27
And setTimeout takes a function which we'll call later.
12:30
And so by indenting this code, we say we're going to call this code,
12:34
and the option we're going to pass is how long we want
12:37
to wait before we send this code.
12:40
Let's say 3 seconds, so 3000 milliseconds.
12:42
As soon as we get the connection, we're setting up a time out,
12:45
so in 3 seconds we're going to call "socket.emit 'server-update.'"
12:48
So now we just see a slight gap from when we connect
12:52
to when we actually get the message.
12:55
And you'll notice as I was editing,
12:57
we now have a few more of these events being called,
13:00
and that's because socket.io will try to reconnect
13:03
the socket any time we disconnect,
13:06
and every time we save that file, our server actually restarts
13:09
disconnecting our connection, so our page has been sitting here
13:12
listening to the server, but the server has died a couple of times and come back.
13:15
Every time it reestablishes that connection,
13:18
the logic of our server sends out that information.
13:21
Let's just get a fresh session going by refreshing.
13:24
So we've connected, and if we wait about 3 seconds,
13:28
here is a message from the server.
13:31
Now, we'll see a little bit more interesting use of this in a little bit,
13:34
but right now we can kind of see that we have our socket open,
13:37
and whenever something interesting happens,
13:40
we're able to send a message from the server to the client.
13:42
You need to sign up for Treehouse in order to download course files.
Sign up