Sharing Top Content from the Angular-sphere.

Showing online users using Nodejs and Socket.io

  • * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ userNameCheck(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { (err, result) => { db.close(); callback(result); }); }); } /* * Name of the Method : login * Description : login the user.
  • * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ login(data,callback){ console.log(data); this.Mongodb.onConnect( (db,ObjectID) => { data ,[], {$set: {‘online’: ‘Y’}},{},(err, result) => { db.close(); callback(err,result.value); }); }); } /* * Name of the Method : registerUser * Description : register the User * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ registerUser(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { (err, result) =>{ db.close(); callback(err,result); }); }); } /* * Name of the Method : userSessionCheck * Description : to check if user is online or not.
  • * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ this.Mongodb.onConnect( (db,ObjectID) => { { _id : ObjectID(data.userId) , online : ‘Y’}, (err, result) => { db.close(); callback(err,result); }); }); } /* * Name of the Method : getUserInfo * Description : to get information of single user.
  • * Parameter : * 1) userId of the user * 2) callback function * Return : callback */ getUserInfo(userId,callback){ this.Mongodb.onConnect( (db,ObjectID) => { { _id : ObjectID(userId)}, (err, result) => { db.close(); callback(err,result); }); }); } /* * Name of the Method : addSocketId * Description : Updates the socket id of single user.
  • toArray((error, queryResult) => { db.close(); callback(error,{ users : result, socketIds : queryResult }); }); }); }); } this.Mongodb.onConnect( (db,ObjectID) => { { socketId: userSocketId} ,[], {$set: {‘online’: ‘N’}},{},(error, result) => { db.close(); if (error) { callback({loggedOut:true}); }else{ if (result===null) { callback({loggedOut:true}); }else{ if (result.online === ‘Y’) { callback({loggedOut:false}); }else{ callback({loggedOut:true}); } } } }); }); } } module.exports = new Helper(); * Name of the Method : userNameCheck * Description : To check if the username is available or not.

In any Real Time chatting app,showing online users play very important role, which need to be updated when a new user comes online or an online user goes of

@TiwariShanky: Post updated=„Äč Showing online users Nodejs and socket.io

url:

#socket.io
#Nodejs…

In any Real Time chatting application showing a number of online users play very important role, which needs to be updated when a new user comes online or an online user goes offline. So this article explains how we can create such a list of online users.

Here we will use Nodejs for server-side, AngularJs for client-side and Socket.io for real-time updates. Also, in this application, we will create a login and registration functionality.Here we will use MongoDB in order to store user’s  information.

On this Blog, you will find private chat application implemented in Angular 1.x as well as Angular 2 and above.Make sure to check them out and if you feel like giving any suggestions or feature request then please let me know.

Explanation :

Also, read Typing notification in chatting application using nodejs and socket.io

Below you can see the directory structure for our server. In the utils folder, we have our config files, helper file which contains all the method and files to handle routes.

command.

package.json:

¬†¬† “version” : “2.0.0” ,

¬†¬† “description” : “Showing online users using Nodejs and Socket.io” ,

¬†¬† “main” : “server.js” ,

¬†¬† “scripts” : {

¬†¬†¬†¬† “test” : “echo \”Error: no test specified\” && exit 1″

¬†¬† “keywords” : [

¬†¬†¬†¬† “Showing” ,

¬†¬†¬†¬† “online” ,

¬†¬†¬†¬† “users” ,

¬†¬†¬†¬† “using” ,

¬†¬†¬†¬† “Nodejs” ,

¬†¬†¬†¬† “and” ,

¬†¬† “author” : “Shashank Tiwari” ,

¬†¬† “license” : “MIT” ,

¬†¬† “dependencies” : {

¬†¬†¬†¬† “body-parser” : “^1.17.2” ,

¬†¬†¬†¬† “ejs” : “^2.5.6” ,

¬†¬†¬†¬† “express” : “^4.15.3” ,

¬†¬†¬†¬† “mongodb” : “^2.2.28” ,

¬†¬†¬†¬† “socket.io” : “^2.0.2”

Now let’s create our server.js file and write down the below code. In the below code, we will initialize the routes for the application and socket events. Also, we will add the application configuration for this current application setup.

As shown below, we will first setup configutation for the application and we will initiate the application’s routing and socket events.

server.js:

Here, I am not going to talk about the login and registration. You will find the code related to that in the source code of this application. The routes.js is fully utilized in the login and registration.

Noe let’s create socket.js inside utils folder and write down the below into it.In this file, we will write the socket events which will push the real-time updates to the client.

socket.js:

‘use strict’ ;

const helper = require ( ‘./helper’ ) ;

¬†¬†¬†¬†¬†¬†¬†¬† this . io . on ( ‘connection’ , ( socket ) = > {

¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† socket . on ( ‘chat-list’ , ( data ) = > {

¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† socket . on ( ‘logout’ , ( data ) = > {

¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† socket . on ( ‘disconnect’ , ( ) = > {

¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† let userID = socket . request . _query [ ‘userId’ ] ;

socketEvents().

socketConfig()

method, In this method, if you notice we are storing the socket id and updating the online status of the user respectively who connects to chat application.

Here I am sending the user id of the user from the angular application, in order to update the socket id and online status.

In 

socketEvents()

 method, we are listening 

chat-list

logout

and

disconnect

socket events on the server side.

On

chat-list

Here we covered our server side application setup and created the REST API. Also, integrated the socket.io on the server side and created the events required for our application.

Now let’s create a helper.js file inside utils directory and write the down below code. In the below code snippet, I have written each method’s name, description, and parameters required to that respective method.

helper.js:

/* * Showing online users using Nodejs and Socket.io * @author Shashank Tiwari */ ‘use strict’; class Helper{ constructor(){ this.Mongodb = require(“./db”); } /* * Name of the Method : userNameCheck * Description : To check if the username is available or not. * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ userNameCheck(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).find(data).count( (err, result) => { db.close(); callback(result); }); }); } /* * Name of the Method : login * Description : login the user. * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ login(data,callback){ console.log(data); this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).findAndModify( data ,[], {$set: {‘online’: ‘Y’}},{},(err, result) => { db.close(); callback(err,result.value); }); }); } /* * Name of the Method : registerUser * Description : register the User * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ registerUser(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).insertOne(data, (err, result) =>{ db.close(); callback(err,result); }); }); } /* * Name of the Method : userSessionCheck * Description : to check if user is online or not. * Parameter : * 1) data query object for MongDB * 2) callback function * Return : callback */ userSessionCheck(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).findOne( { _id : ObjectID(data.userId) , online : ‘Y’}, (err, result) => { db.close(); callback(err,result); }); }); } /* * Name of the Method : getUserInfo * Description : to get information of single user. * Parameter : * 1) userId of the user * 2) callback function * Return : callback */ getUserInfo(userId,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).findOne( { _id : ObjectID(userId)}, (err, result) => { db.close(); callback(err,result); }); }); } /* * Name of the Method : addSocketId * Description : Updates the socket id of single user. * Parameter : * 1) userId of the user * 2) callback function * Return : callback */ addSocketId(data,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).update( { _id : ObjectID(data.id)}, data.value ,(err, result) => { db.close(); callback(err,result.result); }); }); } /* * Name of the Method : logout * Description : To logout the loggedin user. * Parameter : * 1) userID * 2) callback function * Return : callback */ logout(userID,callback){ const data = { $set :{ online : ‘N’ } }; this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).update( {_id : ObjectID(userID)}, data ,(err, result) => { db.close(); callback(err,result.result); }); }); } /* * Name of the Method : getChatList * Description : To get the list of online user. * Parameter : * 1) userId (socket id) of the user * 2) callback function * Return : callback */ getChatList(userId,callback){ this.Mongodb.onConnect((db,ObjectID) => { console.log(userId); db.collection(‘users’).find({_id:{ $ne:ObjectID(userId) } },{ username:1,online: 1,socketId:1}).toArray((error, result) => { db.collection(‘users’).find({ _id:{ $ne:ObjectID(userId) } },{socketId: 1}).toArray((error, queryResult) => { db.close(); callback(error,{ users : result, socketIds : queryResult }); }); }); }); } isUserLoggedOut(userSocketId,callback){ this.Mongodb.onConnect( (db,ObjectID) => { db.collection(‘users’).findAndModify( { socketId: userSocketId} ,[], {$set: {‘online’: ‘N’}},{},(error, result) => { db.close(); if (error) { callback({loggedOut:true}); }else{ if (result===null) { callback({loggedOut:true}); }else{ if (result.online === ‘Y’) { callback({loggedOut:false}); }else{ callback({loggedOut:true}); } } } }); }); } } module.exports = new Helper();

‘use strict’ ;

this . Mongodb = require ( “./db” ) ;

* Name of the Method : userNameCheck

* Description : To check if the username is available or not.

* Parameter :

* 1) data query object for MongDB

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . find ( data ) . count ( ( err , result ) = > {

db . close ( ) ;

callback ( result ) ;

* Name of the Method : login

* Description : login the user.

* Parameter :

* 1) data query object for MongDB

* 2) callback function

* Return : callback

console . log ( data ) ;

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . findAndModify ( data , [ ] , { $ set : { ‘online’ : ‘Y’ } } , { } , ( err , result ) = > {

db . close ( ) ;

callback ( err , result . value ) ;

* Name of the Method : registerUser

* Description : register the User

* Parameter :

* 1) data query object for MongDB

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . insertOne ( data , ( err , result ) = > {

db . close ( ) ;

callback ( err , result ) ;

* Name of the Method : userSessionCheck

* Description : to check if user is online or not.

* Parameter :

* 1) data query object for MongDB

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . findOne ( { _id : ObjectID ( data . userId ) , online : ‘Y’ } , ( err , result ) = > {

db . close ( ) ;

callback ( err , result ) ;

* Name of the Method : getUserInfo

* Description : to get information of single user.

* Parameter :

* 1) userId of the user

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . findOne ( { _id : ObjectID ( userId ) } , ( err , result ) = > {

db . close ( ) ;

callback ( err , result ) ;

* Name of the Method : addSocketId

* Description : Updates the socket id of single user.

* Parameter :

* 1) userId of the user

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . update ( { _id : ObjectID ( data . id ) } , data . value , ( err , result ) = > {

db . close ( ) ;

callback ( err , result . result ) ;

* Name of the Method : logout

* Description : To logout the loggedin user.

* Parameter :

* 1) userID

* 2) callback function

* Return : callback

   $ set : {

¬†¬† online : ‘N’

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . update ( { _id : ObjectID ( userID ) } , data , ( err , result ) = > {

db . close ( ) ;

callback ( err , result . result ) ;

* Name of the Method : getChatList

* Description : To get the list of online user.

* Parameter :

* 1) userId (socket id) of the user

* 2) callback function

* Return : callback

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

console . log ( userId ) ;

db . collection ( ‘users’ ) . find ( { _id : {

$ ne : ObjectID ( userId )

} , { username : 1 , online : 1 , socketId : 1 } ) . toArray ( ( error , result ) = > {

db . collection ( ‘users’ ) . find ( {

_id : {

$ ne : ObjectID ( userId )

} , { socketId : 1 } ) . toArray ( ( error , queryResult ) = > {

db . close ( ) ;

users : result ,

socketIds : queryResult

this . Mongodb . onConnect ( ( db , ObjectID ) = > {

db . collection ( ‘users’ ) . findAndModify ( { socketId : userSocketId } , [ ] , { $ set : { ‘online’ : ‘N’ } } , { } , ( error , result ) = > {

db . close ( ) ;

callback ( { loggedOut : true } ) ;

} else {

callback ( { loggedOut : true } ) ;

} else {

if ( result . online === ‘Y’ ) {

callback ( { loggedOut : false } ) ;

} else {

callback ( { loggedOut : true } ) ;

Now let’s start the implementation of the front end. First we will start with login and registration, In order to do this let’s create index.html inside the views folder and write down below code. Below markup wrote for login and registration, here I am using UI bootstrap for AngularJs.

index.html:

Our login and Registration markup is completed, now let’s start the implementation of the home page. Create the home.html inside the views folder and write down the below code.

home.html:

The above markup is short and sweet, here first you will see the logout option then the ng-repeat for to iterate the list of online/offline users and at the end all the scripts that we have used.

folder. In this file, we will create code login, registration, and home’s code.So basically we will have two controllers here one is for index.html and second on is for home.html. Write down the below code into the script.js file.

/* * Showing online users using Nodejs and Socket.io * @author Shashank Tiwari */ ‘use strict’; const app = angular.module(‘app’,[‘ui.bootstrap’]); app.factory(‘socket’, function ($rootScope) { let socket = null; return { connect: function(userId){ socket = io.connect({query: `userId=${userId}`}); }, on: function (eventName, callback) { socket.on(eventName, function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); }, emit: function (eventName, data, callback) { socket.emit(eventName, data, function () { var args = arguments; $rootScope.$apply(function () { if (callback) { callback.apply(socket, args); } }); }) } }; }); app.service(‘appService’, function (socket,$http) { return new AppService($http); }); app.controller(‘app’, function ($scope,$timeout,socket,appService) { $scope.UI = { isUsernameAvailable : true, typingTimer : null }; $scope.form = { username : null, password : null, isUsernameSuggest : null, registerPassword:null }; var typingTimer = null; $scope.usernameCheck = function(){ $timeout.cancel($scope.UI.typingTimer); $scope.UI.typingTimer = $timeout(()=>{ if ($scope.form.isUsernameSuggest !== undefined || $scope.form.isUsernameSuggest !==”) { appService.usernameCheck( { username:$scope.form.isUsernameSuggest, }, (response)=>{ if(!response.error) { $scope.UI.isUsernameAvailable = true; }else{ $scope.UI.isUsernameAvailable = false; } }); } },800); } $scope.login = function (){ if ($scope.form.username === undefined || $scope.form.username ===”) { alert(‘Invalid username.’); }else if($scope.form.password === undefined || $scope.form.password ===”) { alert(‘Invalid password.’); }else{ appService.login({ username:$scope.form.username, password:$scope.form.password }, (response)=>{ if (response.error) { alert(response.message); }else{ window.location.href = ‘/home/’+response.userId; } }); } } $scope.register = function (){ if ($scope.form.isUsernameSuggest === undefined || $scope.form.isUsernameSuggest ===”) { alert(‘Invalid username.’); }else if($scope.form.registerPassword === undefined || $scope.form.registerPassword ===”) { alert(‘Invalid password.’); }else{ appService.register({ username:$scope.form.isUsernameSuggest, password:$scope.form.registerPassword }, (response)=>{ if (response.error) { alert(response.message); }else{ window.location.href = ‘/home/’+response.userId; } }); } } }); app.controller(‘home’, function ($scope,$timeout,socket,appService) { $scope.UI = { username : null, typingTimer : null, results : null }; appService.userSessionCheck((response)=>{ if (response.error) { window.location.href=’/’; }else{ $scope.UI.username = response.username; let userId = appService.getUserid(); socket.connect(userId); socket.emit(‘chat-list’,{userId:userId}); socket.on(‘chat-list-response’,(response)=>{ if (response.singleUser) { let chatListUsers = $scope.UI.results.filter( ( obj ) =>{ if(obj._id === response.chatList[‘_id’]){ return false; }else{ return true; } }); $scope.UI.results = chatListUsers; $scope.UI.results.push(response.chatList); }else if(response.userDisconnected){ if ($scope.UI.results.length > 1) { let chatListUsers = $scope.UI.results.filter( ( obj ) =>{ if(obj.socketId === response.socketId){ obj.online = ‘N’; } return true; }); $scope.UI.results =chatListUsers; } }else{ $scope.UI.results = response.chatList; } }); } }); $scope.logout = function(){ socket.emit(‘logout’,{userId:appService.getUserid()}); socket.on(‘logout-response’,(response)=>{ if (!response.error) { window.location.href=’/’; } }); } $scope.getClassName = function(isOnline){ if (isOnline===’N’) { return ‘user-offline’; }else{ return ‘user-online’; } } $scope.getOnlineStatus = function(isOnline){ if (isOnline===’N’) { return ‘Offline’; }else{ return ‘Online’; } } });

‘use strict’ ;

const app = angular . module ( ‘app’ , [ ‘ui.bootstrap’ ] ) ;

app . factory ( ‘socket’ , function ( $ rootScope ) {

     let socket = null ;

connect : function ( userId ) {

socket = io . connect ( { query : ` userId = $ { userId } ` } ) ;

on : function ( eventName , callback ) {

socket . on ( eventName , function ( ) {   

var args = arguments ;

$ rootScope . $ apply ( function ( ) {

   callback . apply ( socket , args ) ;

emit : function ( eventName , data , callback ) {

   socket . emit ( eventName , data , function ( ) {

var args = arguments ;

$ rootScope . $ apply ( function ( ) {

callback . apply ( socket , args ) ;

app . service ( ‘appService’ , ¬†¬† function ( socket , $ http ) {

return new AppService ( $ http ) ;

app . controller ( ‘app’ , ¬†¬† function ( $ scope , $ timeout , socket , appService ) {

$ scope . UI = {

isUsernameAvailable : true ,

typingTimer : null

$ scope . form = {

username : null ,

password : null ,

isUsernameSuggest : null ,

registerPassword : null

var typingTimer =    null ;

$ scope . usernameCheck = function ( ) {

$ timeout . cancel ( $ scope . UI . typingTimer ) ;

$ scope . UI . typingTimer = $ timeout ( ( ) = > {

if ( $ scope . form . isUsernameSuggest !== undefined || $ scope . form . isUsernameSuggest !== ” ) {

appService . usernameCheck ( {

username : $ scope . form . isUsernameSuggest ,

if ( ! response . error ) {

$ scope . login = function ( ) {

if ( $ scope . form . username === undefined || $ scope . form . username === ” ) {

alert ( ‘Invalid username.’ ) ;

} else if ( $ scope . form . password === undefined || $ scope . form . password === ” ) {

alert ( ‘Invalid password.’ ) ;

appService . login ( {

username : $ scope . form . username ,

password : $ scope . form . password

if ( response . error ) {

alert ( response . message ) ;

window . location . href = ‘/home/’ + response . userId ;

$ scope . register = function ( ) {

alert ( ‘Invalid username.’ ) ;

alert ( ‘Invalid password.’ ) ;

appService . register ( {

username : $ scope . form . isUsernameSuggest ,

password : $ scope . form . registerPassword

if ( response . error ) {

alert ( response . message ) ;

window . location . href = ‘/home/’ + response . userId ;

app . controller ( ‘home’ , ¬†¬† function ( $ scope , $ timeout , socket , appService ) {

$ scope . UI = {

username : null ,

typingTimer : null ,

results : null

if ( response . error ) {

window . location . href = ‘/’ ;

$ scope . UI . username = response . username ;

let userId = appService . getUserid ( ) ;

socket . connect ( userId ) ;

socket . emit ( ‘chat-list’ , { userId : userId } ) ;

socket . on ( ‘chat-list-response’ , ( response ) = > {

if ( response . singleUser ) {

if ( obj . _id === response . chatList [ ‘_id’ ] ) {

return false ;

return true ;

$ scope . UI . results . push ( response . chatList ) ;

if ( $ scope . UI . results . length > 1 ) {

if ( obj . socketId === response . socketId ) {

obj . online = ‘N’ ;

return true ;

$ scope . UI . results = response . chatList ;

$ scope . logout = function ( ) {

socket . emit ( ‘logout’ , { userId : appService . getUserid ( ) } ) ;

socket . on ( ‘logout-response’ , ( response ) = > {

if ( ! response . error ) {

window . location . href = ‘/’ ;

$ scope . getClassName = function ( isOnline ) {

return ‘user-offline’ ;

return ‘user-online’ ;

return ‘Offline’ ;

return ‘Online’ ;

In the above code,

First, we have created a socket factory method, where I am connecting socket server with the client by passing the userId of the user. Here I have created a separate class named as appService and I am using that class to create angular js service. We will take a look appService class after some time.

But before that let’s understand the both controllers. Here app controller si used for index.html, in other words, we are using the app controller for login and registration.I think the app controller is very easy to understand so I won’t talk much about it.

In the home controller, we have logic behind showing the online and offline user, So let’s break the code and understand it.

Here, we are capturing the userId of the user from the Url by using the appService class. If in any case userId found null or blank then on the next line we will redirect the user to login page.

method for an obvious reason.

we are updating the list of the user, by using the socket on and emit event. For example, If a new user logs in into the system or an existing user goes offline in both the cases we will update the list of online users.

Now, here I am emitting the complete list of users to the user who just logged into the system.

And, the for the rest of users, those who are already online will get the users information who went offline or just logged in.

This makes sense, right? Because sending the complete list of online users to each and every user is not good.

code block, http for the below task.

folder and write down the below code.

alert ( ‘Invalid Server call’ ) ;

method : ‘POST’ ,

message : ‘Invalid username.’

message : ‘Invalid password.’

url : ‘/login’ ,

message : ‘Invalid username.’

url : ‘/usernameCheck’ ,

message : ‘Invalid username.’

message : ‘Invalid password.’

url : ‘/registerUser’ ,

const urlData = ( window . location . pathname ) . split ( ‘/’ ) ;

window . location . herf = ‘/’ ;

url : ‘/userSessionCheck’ ,

So for this article that’s it.If you find this article useful consider sharing this on your social media and let the other people know about it and if you feel like giving me any suggestions please comment in below comment box.

I will add this fix ASAP and if you already have an idea about this issue, please comment below it will help other readers too.

Showing online users using Nodejs and Socket.io

Comments are closed, but trackbacks and pingbacks are open.