Skip to content

Instantly share code, notes, and snippets.

@i-Robi
Last active May 7, 2018 22:03
Show Gist options
  • Save i-Robi/9205904 to your computer and use it in GitHub Desktop.
Save i-Robi/9205904 to your computer and use it in GitHub Desktop.

Creating a simple Node.js - Express - socket.io app

Installing packages

Node.js and npm

Dowload Node.js from their website and install the package. npm should be in there.

Express

To install express globally on your machine, type the following in the terminal:

npm install -g express

This will allow to create an app directly with the express command.

Creating the application

Create the app skeleton

Run the following command in the terminal:

express yourapp -ejs

This will create a folder yourapp with all the files necessary for the creation of an express app. The option -ejs indicates that we will use the EJS template engine (the the HTML files). By default, express uses the Jade template engine, which might be more complicated as a start.

In the yourapp folder, you will notice a file package.json. It is basically the DNA of your app: this file tells Node everything about your app, including how to run it. Node is a modular framework with many addons built by the community — express is one of them. All the addons you want to use for your app are listed in the "dependencies" entry in the package.json file. So far, you should see express and EJS. Let's install them:

npm install

This command will install all the dependencies in a new folder node_modules.

Now we are ready to launch our app for the first time:

node app.js

You should be able to see the result at the following address: http://localhost:3000.

Install socket.io

Go to the yourapp folder and type:

npm install socket.io --save

The --save option wil automatically add the socket.io dependency to the package.json file.

Server side

Now go to the app.js file and replace the content by:

/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

// create the express app with socket.io
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

// routes
app.get('/', routes.index);
app.get('/users', user.list);

// port
server.listen(app.get('port'));

// socket.io code
io.sockets.on('connection', function (socket) {

  // your client / server communication code (server side)
  // ...

});

Basically, the changes here are that we require the socket.io package and listen to the server that was created from the express app (lines 12–14). At the end of the file, we tell the server to wait for a client connection and to execute some code.

Client side

Let's set up socket.io in the client as well. In views/index.ejs, add the following line in the head tag:

<script src="/socket.io/socket.io.js"></script>

Finally, create a script in the body element:

<script>
  var socket = io.connect(document.URL);
</script>

And now we just have to make the client and server communicate with each other.

Client / server communication

In app.js (the server), let's write the code that gets exectuted after a client connected. Replace the // your client / server communication code (server side) line by:

socket.emit('message_sent_by_the_server', { hello: 'world' });

This line will send to everyone the message message_sent_by_the_server, with some data associated with it (namely, { hello: 'world' }).

Let's tell the client the behavior to adopt. In the script where we defined the socket variable in views/index.ejs, let's add the following:

socket.on('message_sent_by_the_server', function(data) {
  console.log(data);
});

Now if you go to http://localhost:3000 in your browser (don't forget to restart your server before!) and open the javascript console, you should see the object {hello: "world"}, which is the data that was sent by the server.

The pattern socket.emit / socket.on works the other way around too, if the client wants to send a message to the server. In views/index.ejs, let's replace what we just added by:

socket.on('message_sent_by_the_server', function(data) {
  console.log(data);
  socket.emit('message_sent_by_the_client', { my: 'message' });
});

And on the server side (in app.js), let's add a second instruction:

io.sockets.on('connection', function (socket) {

  socket.emit('message_sent_by_the_server', { hello: 'world' });

  socket.on('message_sent_by_the_client', function (data) {
    console.log(data.my);
  });

});

So here is what happens when the client connects to the server:

  • The server sends the message message_sent_by_the_server with some data to everyone
  • The clients receives the message and:
    • Displays the data in the client's console {hello: "world"}
    • Sends the message message_sent_by_the_client with some data to everyone
  • The server receives the client's message and displays the content of the my attribute in the console, i.e. message.

Congratz, you have your first Node.js — Express — socket.io application working!

A few tricks to improve the development stack

Restarting the server automatically with nodemon

So far, if you want to see your changes in the browser, you have to restart your server each time you update a file. There is an npm package that does it for you: nodemon. Each time you modify a file, it will restart the server automatically. Let's install it:

npm install nodemon --save-dev

Once again, the --save options will automatically update the package.json file, and the -dev option indicates that we create a dependency that is meant to be used only in development mode. Lastly, we have to update the package.json file to indicate that we want to run the app with nodemon instead of node. In the "script" entry, replace the "start": "node app.js" by "start": "nodemon app.js".

To launch your app, you can now type in the terminal:

npm start

Hiding the socket.io debug messages

You might have noticed that the server console get flooded with socket.io debug messages. If you want to remove them, just add this line to app.js:

io.set('log level', 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment