Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Building AngularJS Applications with Socket.IO

In this tutorial, we will take a look at Socket.IO in order to build an Angular JS application. The primary idea here is to build a chat application, since Socket.IO is primarily used for developing communication applications.

AngularJS happens to be a great framework for JavaScript that allows for two-way data binding further making it possible for fast and easy usage. It is also a very powerful directive system that assists in the creation of custom components that are reusable in nature. Coupling AngularJS with Socket.IO, we will learn the method to add real-time features, and then build an instant messaging application.

However, just before we do that, we shall take a look at what AngularJS and Socket.IO actually are.

Note: Directives are new attributes used by AngularJS to extend HTML. AngularJS comes with a set of built-in directives with the prefix 'ng-'. You can also define your own directives as per application requirement.

What is AngularJS?

AngularJS is basically an open-source web development framework that helps in addressing several issues faced by developers when creating applications that are on a single page. Both development and testing are made relatively easier, as it provides a framework for client-side MVC AND MVVM architectures. Besides this, it also provides components that are largely used in rich Internet applications.

At present, the development work on AngularJS is maintained by corporations and individuals, including Google.

What is Socket.IO?

Socket.IO happens to be a JavaScript library meant for real-time applications on the web. It allows for real-time, two directional communications between clients and servers. Socket.IO consists of two basic parts: a client side library running on the browser and a node.js server-side library. These parts have pretty much the same API and are event driven.

Socket.IO is mainly used in the form of a wrapper for WebSocket and also provides several other features such as data storage (on the client), broadcast to multiple sockets and asynchronous I/O. it can be largely used for the implementation of real-time analytics, instant messaging and chat applications, binary streaming and also document collaboration.

Now that we know about Socket.IO and AngularJS, we shall learn to build a chat application using them.

Some prerequisites

To get started on the application building process, the very first thing that is required is the AngularJS Socket.IO seed. This is available on GitHub and we shall take a look at it. Also, you can either download this repository in zip form or even clone it. That would allow you to get started right away.

Angular Socket.IO seed

The Angular socket.io seed is basically a skeleton for an application buildup and makes use of AngularJS on the front end, and Socket.IO, Express and Node on the backend. It makes use of web sockets for the addition of real time functionalities. Also, if you don’t plan to make use of web sockets in your application, an alternate option is to use Angular Express Seed in place of it.

The seed usually consists of test libraries and angular libraries, along with a bunch of scripts that allow for instant web development. It also shows the method to join together Angular client-side components along with Socket.IO and Express on the server-side.

Directory layout of the seed

app.js                  --> app configuration
bower.json              --> for bower
package.json            --> for npm
public/                 --> contain all files that are to be used on the client side
  css/                  --> css files
    app.css             --> default stylesheet
  img/                  --> all image files
  js/                   --> all javascript files
    app.js              --> declaring top-level app module
    controllers.js      --> all application controllers
    directives.js       --> custom angular directives
    filters.js          --> all custom angular filters
    services.js         --> all custom angular services
  bower_components/
    angular/            --> angular.js
    angular-socket-io/  --> socket.io adapter for angular js
routes/
  index.js              --> route for serving HTML pages and partials
views/
  index.jade            --> main page for the application
  layout.jade           --> doctype, title, head boilerplate
  partials/             --> angular view partials (partial jade templates)
    partial1.jade
    partial2.jade

Now, once you have gotten the Angular Socket.IO seed, you will also require a few dependencies along with npm. You can open up the terminal within the directory of the seed and then run the following. This command will install the required dependencies for the project.

npm install

Once these dependencies have been installed, you can look to run the skeleton version of the app, using command

node app.js

Also, you can see the same in your browser by going to http://localhost:3000, which will allow you to know whether the seed is working as it is supposed to.

Deciding on the features of the application

When one is looking to build a chat application, it is certain that there are many methods that can be followed. However, it is important to take note of those features that you wish to have in your application.

In the application that we shall build, we will have just one chat room where all users can be present. The users can choose their own names and also change them, but they need to be unique as well. This is ensured by the server, as it is responsible for enforcing and announcing any user name changes. Also, a list of messages and users in the chat room at a given point of time are to be exposed by the client.

Developing the front end

Using Jade, we shall build a simple front end to this application, which will provide us with the necessary UI elements. To do so, you will need to open up views/index.jade and then insert the code that follows after, within the block.

Listing 1: The front-end

div(ng-controller='AppCntrl')
.col
  h3 All Messages
  .overflowable
    p(ng-repeat='message in messages') : 
.col
  h3 All Users
  .overflowable
    p(ng-repeat='user in users') 
.clr
  form(ng-submit='sendMessage()')
    | Message: 
    input(size='70', ng-model='message')
    input(type='submit', value='Send')
.clr
  h3 Please change your name
  p Your present user name is 
  form(ng-submit='changeName()')
    input(ng-model='newName')
    input(type='submit', value='Change_Name') 
 

Now, after this step you can go to public/css/app.css and then add the CSS for providing columns and overflows.

Listing 2: Front-end CSS

/* Css stylesheet for front end */
.overflowable {
  height: 244px;
  overflow-y: auto;
  border: 1px solid #000;
}
.overflowable p {
  margin: 2;
}
/* the grid system  layout*/
.col {
  float: left;
  width: 354px;
}
.clr {
  clear: both;
} 
 

Interaction with Socket.IO

Socket.IO is known to expose an io variable on the window. But the better way is to have it enclosed in AngularJS’s Dependency Injection system. Keeping that in mind, we shall start by writing a service that can wrap the socket object that is returned by Socket.IO. This is also a very good step, as it will help in making the controller easier to test later on.

In order to do that, we open public/js/services.js and then replace the content in it with what is given below.

Listing 3: Wrapping of the socket object

app.factory('socket', function ($rootScope) {
  var sockt = io.connect();
  return {
    on: function (eName, callback) {
      sockt.on(eName, function () {  
        var argus = argmts;
        $rootScope.$apply(function () {
          callback.apply(socket, argus);
        });
      });
    },
    emit: function (eName, data, callback) {
      socket.emit(eName, data, function () {
        var argus = argmts;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(sockt, argus);
          }
        });
      })
    }
  };
}); 
 

Now, you might have noticed how we have wrapped each socket callback within $scope.$apply. This basically lets AngularJS know that it requires to check the state of the application and then further update the templates, if there has been a change after running callback that has been passed to it. Internally, $http is known to work in the very same manner, i.e. calls $scope.$apply after some XHR returns that allows AngularJS to update views in accordance.

However, it must also be noted that the entire Socket.IO API is not wrapped by this service.

Now, for our controller, just like for $http, we can ask for the socket object as well.

 function AppCntrl($scope, sockt) 
{
  /* Write your Logic for the Controller */
}
 

Now, we are going to add some logic that will allow us to send and receive messages. To do that, one will need to open js/public.controllers.js and then replace the contents found there with what has been provided below.

Listing 4: Adding logic to the controller

function AppCntrl($scope, sockt) {
  sockt.on('init', function (data) {
    $scope.name = data.name;
    $scope.users = data.users;
  });
  sockt.on('send:message', function (message) {
    $scope.messages.push(message);
  });
  sockt.on('change:name', function (data) {
    changeName(data.oldName, data.newName);
  });
  sockt.on('user:join', function (data) {
    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + data.name + ' has joined.'
    });
    $scope.users.push(data.name);
  });
  // add a message when a user disconnects or leaves the room
  sockt.on('user:left', function (data) {
    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + data.name + ' has left the room.'
    });
    var j, user;
    for (j = 0; j < $scope.users.length; j++) {
      user = $scope.users[j];
      if (user === data.name) {
        $scope.users.splice(j, 1);
        break;
      }
    }
  });
  var changeName = function (oldName, newName) {
    // rename user in list of users 
    var j;
    for (j = 0; j < $scope.users.length; j++) {
      if ($scope.users[j] === oldName) {
        $scope.users[j] = newName;
      }
    }
    $scope.messages.push({
      user: 'chatroom',
      text: 'User ' + oldName + ' is now changed to ' + newName + '.'
    });
  }
  $scope.changeName = function () {
    socket.emit('change:name', {
      name: $scope.newName
    }, function (result) {
      if (!result) {
        alert('There was an error during name change');
      } else {
        changeName($scope.name, $scope.newName);
        $scope.name = $scope.newName;
        $scope.newName = '';
      }
    });
  };
   $scope.sendMessage = function () {
    socket.emit('send:message', {
      message: $scope.message
    });
    $scope.messages.push({
      user: $scope.name,
      text: $scope.message
    });
    $scope.message = '';
  };
} 
 

As this application will only feature one view, we will remove the routing from public/js/app.js and then simplify it to –

// Declaring the app level module that is dependent on filters and services

var app = angular.module('myApp', ['myApp.filters', 'myApp.directives']); 

Writing of the server

The next option is to open route/socket.js. Here we need to define the object that will maintain the state of the server, such that the user names are unique.

Listing 5: Maintaining the state of the server

var userallnames = (function () {
  var allnames = {};
  var claim = function (name) {
    if (!name || userallnames[name]) {
      return false;
    } else {
      userallnames[name] = true;
      return true;
    }
  };
  var gtGuestName = function () {
    var name,
      nxtUsrId = 1;
    do {
      name = 'Guest is ' + nxtUsrId;
      nxtUsrId += 1;
    } while (!claim(name));
    return name;
  };
  var get = function () {
    var res = [];
    for (user in userallnames) {
      res.push(user);
    }
    return res;
  };
  var fre = function (name) {
    if (userallnames[name]) {
      delete userallnames[name];
    }
  };
  return {
    claim: claim,
    fre: fre,
    get: get,
    gtGuestName: gtGuestName
  };
}()); 
 

This provides a set of names, along with APIs that makes more of a sense for the domain of any chat server. We shall get this up to the server’s socket to see the response to the calls made by our client.

Listing 6: Checking response to calls

module.exports = function (sockt) {
  var Name = usrNames.getGuestName();
    sockt.emit('init', {
    Name: Name,
    users: usrNames.get()
  });
    sockt.broadcast.emit('user:join', {
    Name: Name
  });
    sockt.on('send:message', function (data) {
    sockt.broadcast.emit('send:message', {
      user: Name,
      text: data.message
    });
  });
    sockt.on('change:Name', function (data, fn) {
    if (usrNames.claim(data.Name)) {
      var oldName = Name;
      usrNames.free(oldName);
      Name = data.Name;
      sockt.broadcast.emit('change:Name', {
        oldName: oldName,
        newName: Name
      });
      fn(true);
    } else {
      fn(false);
    }
  });
    sockt.on('disconnect', function () {
    sockt.broadcast.emit('user:left', {
      Name: Name
    });
    usrNames.free(Name);
  });
}; 
 

With the step, the chat application that we set out to make would be complete. The only step left would be to run the application using node app.js. Also, due to Socket.IO, the application should largely update in real-time.

The output will be shown as below.

Figure 1: Showing chat output window

Conclusion

While we have prepared a very simple and basic chat application, a lot more can still be done on this. For example, one can think of submitting empty messages. You can make use of ng-valid to not allow this to happen on the client-side, and then check on the server. The server could also resort to keeping recent history of the latest messages that allows new users to get a good idea as they enter chat.

Writing Angular applications that make use of other libraries tend to be easy, considering you know how to wrap them up in a service and then notify Angular about changed models. In this tutorial, we have taken a look at the Angular Socket.IO seed and then decided on the features that our chat application should have. Only after doing that, have we really gone on to delve into creating the front-end, linking with Socket.IO and then writing the code for the server.



Website: www.techalpine.com Have 16 years of experience as a technical architect and software consultant in enterprise application and product development. Have interest in new technology and innovation area along with technical...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login