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