Getting Started with Socket.IO, Node.js and Express

Getting Started with Socket.IO, Node.js and Express

Socket.IO enables real-time event-based communication between one or more clients and a server. It works on every platform, browser or device and is fast and reliable. It's often used in analytics, document collaboration, streaming and instant messaging.

Socket.IO is smart, it uses WebSockets if available. If not it fails over to something the browser does support. It's easy to setup and use so let's take a look!

In this tutorial we'll cover setting up a basic Express.js application with Socket.IO. We'll create a simple chat server and show the basics on how a client and server works. If you like to take a look at the code it's up on Github.

Requirements

In this tutorial we'll be using the latest Express and Socket.io versions as of 2017.

  • Express 4
  • Socket.IO 1.7.2

If you're using a later version this tutorial will probably still work. Just keep in mind this is what I've tested with.

Getting Started

We'll assume before we begin that you have node and npm installed. If not, I'd highly recommend downloading and installing NVM. NVM is a version manager for node. It's available on Mac, Windows and Linux so you have no excuse for not using it. Once node is installed you'll have access to npm, the node package manager.

Let's create a blank project!

$ mkdir socket-app
$ cd socket-app
$ npm init

The npm init command will create an empty project with a package.json file. If you like you can answer all the questions. If not just press enter through all of it.

We need to install Express and Socket.IO and save them to our package.json file for later.

$ npm install socket.io express --save

The --save will make sure the package will appear in our dependencies in the package.json file. This is important, so we can later install the packages again if needed without having to remember them all.

In past tutorials I suggested at this point to install bower. Bower is a package manager for the web. It can handle a lot of things from frameworks, libraries, assets and utilities.

Unfortunately, there are some problems with using bower so I'd recomend with just sticking with npm.

For this simple example we'll use npm to install jquery.

$ npm install jquery --save

That should be it! The last command will save jquery to our package.json file and download everything into the node_modules folder.

Express Server

Let's begin by creating an express server that displays Hello World. I talked a lot about Express in my getting started guide. Check it out if you need help.

Create a new file called app.js in your socket-app folder.

// app.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);

app.use(express.static(__dirname + '/node_modules'));
app.get('/', function(req, res,next) {
    res.sendFile(__dirname + '/index.html');
});

server.listen(4200);

Lots of things are happening in this file. First we are requiring Express, and creating a new server. We are then requiring Socket.IO. We are setting the static folder to '/node_modules' since we are using npm to server up jQuery and we want to be able to reference it in our html.

App.get routes http requests to the specified path with a specific call back function. The 'res' object represents the HTTP response that an Express app sends when it gets a request. The 'sendFile' just sends the file at the specific path. We'll be creating the index.html in a second. 'server.listen' will open a port and listen for requests coming in.

Create a new index.html file. This will display our "Hello World" message.

<!doctype html>
<html lang="en">
    <head>

    </head>
    <body>
        <h1>Hello World!</h1>
        <div id="future"></div>
        <form id="form" id="chat_form">
            <input id="chat_input" type="text">
            <input type="submit" value="Send">
        </form>
         <script src="/jquery/dist/jquery.js"></script>
        <script src="/socket.io/socket.io.js"></script>
    </body>
</html>

This just simple html with a form box and a div. As you can see from the bottom the script src are pointing to files in our node_modules folder.

Fire up the server and make sure everything works!

$ node app.js

Open up a browser at http://localhost:4200 and you should see this page. Of course the box doesn't do anything right now, we'll get to that soon.

<img src="/content/images/2017/01/Hello-World.PNG" style="max-width:100%;height:auto" "/>

Client Socket Emit

First thing we want to do is see if we can get the client to connect to the server with Socket.IO and have it respond in the console.

First we'll edit our index.html file. Add this script to the bottom of the file.

<!--Index.html-->
...
<script>
 var socket = io.connect('http://10.1.220.19:4200');
 socket.on('connect', function(data) {
    socket.emit('join', 'Hello World from client');
 });
</script>

The socket.on('connect') is an event which is fired upon a successful connection from the web browser. We then have a function callback that will send to the server the hello world message.

Let's add in this code to the app.js file at the bottom, just before the server.listen.

// app.js
...
io.on('connection', function(client) {
    console.log('Client connected...');

    client.on('join', function(data) {
        console.log(data);
    });

The io.on is listening for connections. When it receives one it will report to the console client connected.... You can then setup a number of individual events for it to listen to from the client. The 'client.on('join') will wait for a message from the client for 'join'. It will then log it to the console.

If we start up our node server again we'll see on the node console the message 'Hello World from client'. Perfect.

<img src="/content/images/2017/01/nodehello.PNG" style="max-width:100%;height:auto" "/>

Server Socket Setup

Let's have the server respond back with a message to the client. Add the emit line after console.log.

// app.js
...
io.on('connection', function(client) {  
    console.log('Client connected...');

    client.on('join', function(data) {
        console.log(data);
        client.emit('messages', 'Hello from server');
    });

The client.emit will send a message back to the client that just connected with a message using 'messages'.

Add a new socket.on messages event in the index.html.

// index.html
...
        socket.on('messages', function(data) {
                alert(data);
        });

Now when a client connects it will send a message to the server and it will trigger a popup.

<img src="/content/images/2017/01/pop.PNG" style="max-width:100%;height:auto" "/>

Putting it all Together

In the previous examples we saw that we can send a message to the server. We can also send a message back to the client. What if we want to send a message to all the clients excluding the socket that started it? We can do easily with broadcast.emit.

First let's update our JavaScript in our index.html

<!--index.html-->
...
<script>
 var socket = io.connect();
 socket.on('connect', function(data) {
    socket.emit('join', 'Hello World from client');
 });
 socket.on('broad', function(data) {
         $('#future').append(data+ "<br/>");
   });

 $('form').submit(function(e){
     e.preventDefault();
     var message = $('#chat_input').val();
     socket.emit('messages', message);
 });
</script>

Here we added in a new JQuery .submit event handler which will prevent the form from submitting and instead send a message to the server with the values of the input field in messages.

In addition, we added a new socket event listener for 'broad' which will simply update our div with the message that was returned.

We'll need to update the server with new broadcast.

// app.js
...
io.on('connection', function(client) {
    console.log('Client connected...');

    client.on('join', function(data) {
        console.log(data);
    });

    client.on('messages', function(data) {
           client.emit('broad', data);
           client.broadcast.emit('broad',data);
    });

});

You can see we are listening on messages. After receiving data we simply inform all other clients, including the socket that sent the message, the data.

If we restart the app.js file we'll see we can now send messages to all other clients when we type anything into our input box and press submit. The div under the hello world message should update.

Open up two browser windows and give it a shot. You should see messages being sent between both of them.

Conclusion

This was a quick introduction on using Express, Socket.IO and Node.js. If your brave enough try to finish this example and create a fully functional chat program. You can see an example of that here.

What do you think of Socket.IO? Do you use it? Leave a comment below!