Real Time chatting app using Nodejs, Mysql, AngularJs and Socket.io – Part 2

In the first part, we created Login and registration page and config files required for our Nodejs server. In this part, we will implement Homepage of our Private Real Time chatting app.

I have divided implementation of homepage into 5 parts as shown below.

  1. Fetching User's information and some other basic operations.
  2. Displaying User's Chat list with current online users.
  3. Sending message unique users .
  4. Showing users available to start a new chat. 
  5. Typing indicator when a user types something in the message box.
  6. Showing PopUp notification when the user receives a new message.

For better understanding I have divided homepage layout into four parts as shown in below image.

 

Single User chat System Layout  private Real Time chatting app

HomePage layout

 

 

1. Creating Helper file:

1. Create a file named as helper.js in middleware folder which contains all necessary function for HomePage. Now write below code in helper.js file. Below is the description of each function that we have created in helper.js file.

  1. queryRunner() : As the name suggest, This function is used to Run MySql queries.
  2. getLastConversationId(): To get last conversation ID.
  3. isConversationPresent(): To check is a conversation is present in conversation Table or not.
  4. insertConversation(): To insert conversation in DB table.
  5. insertMsg(): To insert messages in DB Table.
  6. callMsgAfterConversation():  Function to call insertMsg() function and insertConversation() function ( Just to make our code short ).
  7. saveMsgs(): This function checks whether this conversation is present in DB Table or not by calling isConversationPresent() function. If Conversation exists in DB Table, This function calls callMsgAfterConversation(),Else it calls the  getLastConversationId() function and then executes the   callMsgAfterConversation().
  8. getMsgs(): Used to get all the message between two users.
  9. getUserInfo(): To retrieve the user's  information.
  10. getUserChatList(): To get user's chat list.
  11. getUsersToChat(): Used to get users to start new chat.
  12. mergeUsers(): This function is used to  merge online and offline users.

helper.js:

var self={
    queryRunner:function(data,callback){
    	/*
			Function required to run all the queries.
		*/
		var db_conncetion=data.connection;
		var query=data.query;
		var insert_data=data.insert_data;
		db_conncetion.getConnection(function(err,con){
			if(err){
			  con.release();
			}else{
				db_conncetion.query(String(query),insert_data,function(err,rows){
			    con.release();
			    if(!err) {
			    	callback(rows);
			    } else {
			      console.log(err);  
			      console.log("Query failed");  
			    }        
			  });
			}
		});
	},
	getLastConversationId:function(connection,callback){
		/*
			Function to get last conversation ID.
		*/
		var data={
			query:"SELECT MAX(con_id) as ID FROM conversation",
			connection:connection
		}
		self.queryRunner(data,function(result){
			if(result[0].ID!=null){
				var conversationid=parseInt(result[0].ID);
				conversationid++;
				callback({
					ID:conversationid
				});
			} else{
				callback({
					ID:0
				});
			}

		});
	},
	isConversationPresent:function(data,connection,callback){
		/*
			Function to check conversation is present in DB conversations table.
		*/
		var is_present=false;
		var con_id="";
		var is_present_data={
			query:"select * from conversation where to_id='"+data.to_id+"' and from_id='"+data.from_id+"' or to_id='"+data.from_id+"' and from_id='"+data.to_id+"' limit 1",
			connection:connection
		}
		self.queryRunner(is_present_data,function(result){

			if(result.length>0){
				/* data for callback starts*/
				is_present=true;
				con_id=result[0].con_id;

			} else{
				//data for callback 
				is_present=false;
				con_id=0
			}
			callback({
				is_present:is_present,
				con_id:con_id
			});
		});
	},
	insertConversation:function(data,connection,callback){
		/*
			Function to insert consersation.
		*/	
		var insert_conversation={
			query:"INSERT INTO conversation SET ?",
			connection:connection,
			insert_data:{
				id:'',						
				from_id:data.from_id,
				to_id:data.to_id,
				timestamp:Math.floor(new Date() / 1000),
				con_id:data.con_id
			}
		};
		self.queryRunner(insert_conversation,function(result){
			callback(result.insertId);
		});	
	},
	insertMsg:function(data,connection,callback){
		/*
			Function to insert messages.
		*/
		var data_insert={
			query:"INSERT INTO conversation_reply SET ?",
			connection:connection,
			insert_data:{
				id:'',						
				reply:data.msg,
				from_id:data.from_id,
				to_id:data.to_id,
				timestamp:Math.floor(new Date() / 1000),
				con_id:data.con_id
			}
		};	
		self.queryRunner(data_insert,function(result){
			console.log("msg inserted");
			callback(result)
		});
	},
	callMsgAfterConversation:function(data,connection,callback){
		/*
			Separate Function to insert message and conversation in DB ( Just to make our code short ).
		*/
		var conversation_data={
			to_id:data.to_id,
			from_id:data.from_id,
			con_id:data.conversation_id
		}
		self.insertConversation(conversation_data,connection,function(is_insert_conversation){
			
			/* 
				call 'self.insert_msg' to insert messages 
			*/	
			var insert_msg={
				id:'',
				msg:data.msg,
				from_id:data.from_id,
				to_id:data.to_id,
				timestamp:Math.floor(new Date() / 1000),
				con_id:data.conversation_id
			}
			self.insertMsg(insert_msg,connection,function(is_insert_msg){
				callback({
					msg:data.msg,
					from_id:data.from_id,
					to_id:data.to_id,
					timestamp:Math.floor(new Date() / 1000)
				});
			});
		});
	},
	saveMsgs:function(data,connection,callback){
		
		/*	Calling "self.isConversationPresent" function,
			to check is conversation is already present or not.
		*/
		var check_data={
			to_id:data.to_id,
			from_id:data.from_id
		}
		/* 
			checking 'conversation' is present in Database conversation table
		*/
		self.isConversationPresent(check_data,connection,function(is_present){
				
		
			if(is_present.is_present){
				
				var msg_after_conversation={
					to_id:data.to_id,
					from_id:data.from_id,
					msg:data.msg,
					conversation_id:is_present.con_id
				};

				/* 
					caling 'self.callMsgAfterConversation' to insert message and conversation
				*/
				self.callMsgAfterConversation(msg_after_conversation,connection,function(insert_con_msg){
					self.getUserInfo(data.from_id,connection,function(UserInfo){
						insert_con_msg.name=UserInfo.data.name;
						callback(insert_con_msg);
					});
				});

				
			} else{
				/* 
					call 'self.getLastConversationId' to get last conversation ID 
				*/	
				self.getLastConversationId(connection,function(con_id){
					
					var msg_after_conversation={
						to_id:data.to_id,
						from_id:data.from_id,
						msg:data.msg,
						conversation_id:con_id.ID
					};

					/* 
						caling 'self.callMsgAfterConversation' to insert message and conversation
					*/
					self.callMsgAfterConversation(msg_after_conversation,connection,function(insert_con_msg){
						self.getUserInfo(data.from_id,connection,function(UserInfo){
							insert_con_msg.name=UserInfo.data.name;
							callback(insert_con_msg);
						});
					});
				});
			}

		});
	},
	getMsgs:function(data,connection,callback){
		/*
			Function to get messages.
		*/
		var data={
			query:"select reply as msg,from_id,to_id,timestamp from conversation_reply where from_id='"+data.from_id+"' and to_id='"+data.uid+"' or  from_id='"+data.uid+"' and to_id='"+data.from_id+"' order by timestamp asc",
			connection:connection
		}
		self.queryRunner(data,function(result){
			if(result.length > 0){
				callback(result)
			} else{
				callback(null);
			}
		});
	},
	getUserInfo:function(uid,connection,callback){
		/*
			Function to get user information.
		*/
		var data={
			query:"select id,name,p_photo,online from user where id='"+uid+"'",
			connection:connection
		}
		self.queryRunner(data,function(result){
			if(result.length>0) {
				var user_info="";			
				result.forEach(function(element, index, array){
					user_info={
						name:element.name,
						p_photo:element.p_photo,
						online:element.online
					};	
				});
		    	result_send={
		    		data:user_info,
		    		msg:"OK"
		    	};
		    } else {
		    	result_send={
		    		data:null,
		    		msg:"BAD"
		    	};
		    }
		    callback(result_send);
		});
	},
	getUserChatList:function(uid,connection,callback){
		var data={
			query:"select DISTINCT con_id from conversation where to_id='"+uid+"' or from_id='"+uid+"' order by timestamp desc ",
			connection:connection
		}
		self.queryRunner(data,function(result){
			var dbUsers=[];
			if(result.length>0){
				result.forEach(function(element, index, array){
					var data={
						query:"select u.* from conversation as c left join user as u on \
								  u.id =case when (con_id='"+element.con_id+"' and to_id='"+uid+"') \
								THEN \
								  c.from_id \
								ELSE \
								  c.to_id \
								END \
								where con_id='"+element.con_id+"' and to_id='"+uid+"' or con_id='"+element.con_id+"' and from_id='"+uid+"' limit 1",
						connection:connection
					}
					self.queryRunner(data,function(usersData){
						if(usersData.length>0){
							dbUsers.push(usersData[0]);							
						}
						if(index >= (result.length-1)){
							callback(dbUsers);
						}
					});

				});
			}else{
				callback(null);
			}
		});
	},
	getUsersToChat:function(uid,connection,callback){
		var data={
			query:"SELECT  to_id, from_id FROM conversation WHERE to_id='"+uid+"' OR from_id='"+uid+"' GROUP BY con_id DESC  ",
			connection:connection
		}
		self.queryRunner(data,function(result){
			var dbUsers=[];
			if(result.length>0){
				var filter=[];
				result.forEach(function(element, index, array){
					filter.push(element['to_id']);
					filter.push(element['from_id']);
				});
				filter=filter.join();
				data.query="SELECT * FROM user WHERE id NOT IN ("+filter+")";
			}else{
				data.query="SELECT * FROM user WHERE id NOT IN ("+uid+")";
			}
			self.queryRunner(data,function(usersData){
				callback(usersData);
			});		
		});
	},
	mergeUsers:function(socketUsers,dbUsers,newUsers,callback){
		/*
			Function Merge online and offline users.
		*/
		var tempUsers = [];
		for(var i in socketUsers){
			var shouldAdd = false;
			for (var j in dbUsers){
				if(newUsers=='yes'){
					if (dbUsers[j].id == socketUsers[i].id) {
						shouldAdd = false;
						dbUsers.splice(j,1); //Removing single user						
						break;
					}
				}else{
					if (dbUsers[j].id == socketUsers[i].id) {
						dbUsers[j].socketId = socketUsers[i].socketId;
						shouldAdd = true;
						break;
			       }
				}
			}
			if(!shouldAdd){				
				tempUsers.push(socketUsers[i]);
			}
		}
		if(newUsers=='no'){
			tempUsers = tempUsers.concat(dbUsers);
		}else{
			tempUsers = dbUsers;
		}
		callback(tempUsers);
	}
}
module.exports = self;

2. Creating Homepage:

 1. Fetching User's information:

1.  Create a file called as routes.js  to handle all the home pages routes in middleware folder.

2. When a user successfully logs in than the login redirects the user to the home page by passing UserID in URL. For now, I am not encrypting UserID, But in production, it's a good practice to encrypt URL parameters.

Here I am using this UserID to fetch user information like user's name and Profile photo by using '/get_userinfo' post request.write the below code in routes.js.

routes.js:

/*
    post to handle get_userinfo request
*/
app.post('/get_userinfo', function(req, res){
	var data={
		query:"select id,name,p_photo,online from user where id='"+req.body.uid+"'",
		connection:connection
	}
	helper.queryRunner(data,function(result){
		if(result.length>0) {
			var user_info="";			
			result.forEach(function(element, index, array){
				user_info=element;
			});
	    	result_send={
	    		is_logged:true,
	    		data:user_info,
	    		msg:"OK"
	    	};
	    } else {
	    	result_send={
	    		is_logged:false,
	    		data:null,
	    		msg:"BAD"
	    	};
	    }   
	    res.write(JSON.stringify(result_send));
		res.end();
	});
});

2. Displaying User's Chat list with current online users:

1. When a user comes to homes page, then we send user's detail to socket.io and we store each user with SocketId in an array to keep track of all users. Then we send back the all user's chat list by calling getUserChatList(). When we get result from getUserChatList() function than we call  mergeUsers() function to merge socket users and Database users.

2. To know more about how we keep track of socket users in nodejs read this article .

3. Below is the pictorial representation of the overall process.

chat list workflow private real-time chatting app

Chat List Workflow 

 

1. user 3 logs into the application and login page redirects to HomePage

2. user 3 comes onto the home page we send users information to userInfo socket Event, which keeps track of all socket user.

3. Then we apply forEach/for Loop on entire socket users array.

4. For each user we get chat list by using getUserChatList() function.

5. After that, we call a mergeUsers() function to merge Database chat list and socket users list.

6. Finally, after we send the combined list id user to user 3.

7. On the client side, we show the list of users by AngulrJs.

8. As I said earlier we apply forEach on Socket user array to send updated Chat list to existing socket User, so by this process user 1 and user 2 gets updated chat list .

9. At the client side by socket event, we show the updated list to the users.

real time private chatting app user chat list

User's Chat List 

routes.js :  

//Storing users into array as an object
socket.on('userInfo',function(userinfo){
    
	/*
		Adding Single socket user into 'uesrs' array
	*/
	var should_add=true;
	if(users.length == 0){
		userinfo.socketId=socket.id;
		users.push(userinfo);
	}else{
		users.forEach(function(element, index, array){
			if(element.id == userinfo.id){
	    		should_add=	false;	    		
	    	}
		});
		if (should_add) {
			userinfo.socketId=socket.id;
			users.push(userinfo);
	    };
	}

	/*
		Sending list of users to all users
	*/
	users.forEach(function(element, index, array){	    		
		helper.getUserChatList(element.id,connection,function(dbUsers){
			if(dbUsers === null){
				io.to(element.socketId).emit('userEntrance',users);
			}else{
				helper.mergeUsers(users,dbUsers,'no',function(mergedUsers){
					io.to(element.socketId).emit('userEntrance',mergedUsers);
				});
			}	    			
		});
	});

	should_add=true;
});    

3. Sending messages unique user :

1. As we are displaying the combination of offline and online user list, we need to check whether that person is offline or online.

2. When a user sends any message to any other user, we first call a saveMsgs()  function to save the conversation and message.

3. If that person is offline then will have to update the chat list of Sender (This is applicable to start new chat list).

4. If that person is online, then send the message using socket event io.to(SocketID).emit('getMsg','message'); and here we need not update the sender's or receiver's chat list.

routes.js:

socket.on('sendMsg',function(data_server){

    /*
		calling saveMsgs to save messages into DB.
	*/
	helper.saveMsgs(data_server,connection,function(result){

		/*
			Chechking users is offline or not
		*/
		if(data_server.socket_id==null){
			
			/*
				If offline update the Chat list of Sender. 
			*/
			var singleUser=users.find(function(element){
				return element.id == data_server.from_id;
			});	
			/*
				Calling 'getUserChatList' to get user chat list
			*/
			helper.getUserChatList(singleUser.id,connection,function(dbUsers){
	    		if(dbUsers === null){
	    			io.to(singleUser.socketId).emit('userEntrance',users);
	    		}else{
	    			/*
						Calling 'mergeUsers' to merge online and offline users
					*/
	    			helper.mergeUsers(users,dbUsers,'no',function(mergedUsers){
	    				io.to(singleUser.socketId).emit('userEntrance',mergedUsers);
	    			});
	    		}	    			
	    	});
		}else{
			/*
				If Online send message to receiver.
			*/
			io.to(data_server.socket_id).emit('getMsg',result);
		}
	});	    	  	    
});

4. Showing users available to start a new chat:

1. Users available to chat means, Sender never had a conversation with these users.

2. So to get the list of those users, I have created a function called getUsersToChat() in helper.js  file.

3. After getting the list from Database table we will use mergeUsers() function to merge online and offline users. 

realtime private chatting app available users chat list

List of users to start a new chat 

routes.js:

/*
    post to handle get_users_to_chats request
*/
app.post('/get_users_to_chats', function(req, res){
	/*
    	Calling 'getUsersToChat' to get user chat list
    */
	helper.getUsersToChat(req.body.uid,connection,function(dbUsers){
		/*
			Calling 'mergeUsers' to merge online and offline users
		*/
		helper.mergeUsers(users,dbUsers,'yes',function(mergedUsers){
    		res.write(JSON.stringify(mergedUsers));
    		res.end();
    	});			
	});	
});

5. Retrieving messages from Database:

1. To retrieve messages from the server we will call /get_msgs, this will call a function called getMsgs() written inside helper file.

2. write the below code inside routes.js file.

routes.js:

app.post('/get_msgs', function(req, res){
    /*
    	Calling 'getMsgs' to get messages
    */
	helper.getMsgs(req.body,connection,function(result){
		res.write(JSON.stringify(result));
		res.end();
	});		
});

3. At the cleint side we are using Angulr to render messages on the screen as shown below figure.

private real-time chatting app conversations mesages

Conversations

6. When user Logs out from application:

1. Here we have two situations,

  1. Case 1: When the user actually wants to log out.
  2. Case 2: when user accidently closes the browser window.

2. For both the cases will use socket's disconnect event but for case 1, we will write route as /logout and we will destroy user's session.
3. In  socket's disconnect event we will remove the user who wants to log out from socket users array as shown in below code.

routes.js:

app.get('/logout', function(req, res){
    sessionInfo=req.session;
	var uid=sessionInfo.uid;
	
	var data={
		query:"update user set online='N' where id='"+uid+"'",
		connection:connection
	}
	helper.queryRunner(data,function(result){

		req.session.destroy(function(err) {
			if(err) {
		    	console.log(err);
		  	} else {
		  		io.emit('exit',1);
				res.redirect('/');
		  	}

		});
	});
});

4. Now creating /logout when the user actually wants to log out.

routes.js:

/*
    Removig user when user logs out
*/
socket.on('disconnect',function(){
	var spliceId="";
	for(var i=0;i<users.length;i++){
		if(users[i].id==uIdSocket){
			if(users[i].socketId==socket.id){					
			  	var data={
					query:"update user set online='N' where id='"+users[i].id+"'",
					connection:connection
				}
				spliceId=i;
				helper.queryRunner(data,function(result){
					users.splice(spliceId,1); //Removing single user
					io.emit('exit',users[spliceId]);
				});
			}
		}				
	}

});

Now let's assemble our routes.js file:

routes.js:

var bodyParser = require('body-parser');


// requiring Helper file to run helper functions
var helper = require('./helper');
exports.helper = helper;

var method=routes.prototype;

function routes(app,connection,io,sessionInfo){
    app.use(bodyParser.urlencoded({
		extended: true
	}));
	app.use(bodyParser.json());

	// creating array of users.
	var users=[];
	var uid=""; 


	/*
		Socket event starts
	*/
	io.on('connection',function(socket){



		var uIdSocket=socket.request.session.uid;


		//Storing users into array as an object
	    socket.on('userInfo',function(userinfo){
	    	/*
	    		Adding Single socket user into 'uesrs' array
	    	*/

			var should_add=true;
	    	if(users.length == 0){
	    		userinfo.socketId=socket.id;
	    		users.push(userinfo);
	    	}else{
	    		users.forEach(function(element, index, array){
	    			if(element.id == userinfo.id){
			    		should_add=	false;	    		
			    	}
				});
				if (should_add) {
					userinfo.socketId=socket.id;
	    			users.push(userinfo);
			    };
	    	}

	    	var data={
				query:"update user set online='Y' where id='"+userinfo.id+"'",
				connection:connection
			}
			helper.queryRunner(data,function(result){
				/*
		    		Sending list of users to all users
		    	*/
				users.forEach(function(element, index, array){
		    		helper.getUserChatList(element.id,connection,function(dbUsers){
		    			if(dbUsers === null){
		    				io.to(element.socketId).emit('userEntrance',users);
		    			}else{
		    				helper.mergeUsers(users,dbUsers,'no',function(mergedUsers){
		    					io.to(element.socketId).emit('userEntrance',mergedUsers);
		    				});
		    			}	    			
		    		});
				});
			});

	    	

	    	should_add=true;
	    });    

	   	/*
			'sendMsg' will save the messages into DB.
	   	*/
	   	socket.on('sendMsg',function(data_server){

	    	/*
	    		calling saveMsgs to save messages into DB.
	    	*/
	    	helper.saveMsgs(data_server,connection,function(result){

	    		/*
	    			Chechking users is offline or not
	    		*/
	    		if(data_server.socket_id==null){
	    			
	    			/*
	    				If offline update the Chat list of Sender. 
	    			*/
	    			var singleUser=users.find(function(element){
	    				return element.id == data_server.from_id;
	    			});	
	    			/*
	    				Calling 'getUserChatList' to get user chat list
	    			*/
					helper.getUserChatList(singleUser.id,connection,function(dbUsers){
			    		if(dbUsers === null){
			    			io.to(singleUser.socketId).emit('userEntrance',users);
			    		}else{
			    			/*
	    						Calling 'mergeUsers' to merge online and offline users
	    					*/
			    			helper.mergeUsers(users,dbUsers,'no',function(mergedUsers){
			    				io.to(singleUser.socketId).emit('userEntrance',mergedUsers);
			    			});
			    		}	    			
			    	});
				}else{
					/*
	    				If Online send message to receiver.
	    			*/
	    			io.to(data_server.socket_id).emit('getMsg',result);
	    		}
	    	});	    	  	    
	    });
	   

	    /*
	    	Sending Typing notification to user.
	    */
	    socket.on('setTypingNotification',function(data_server){	    			
	    	io.to(data_server.data_socket_fromid).emit('getTypingNotification',data_server);
	    });

	    /*
	    	Removig user when user logs out
	    */
	    socket.on('disconnect',function(){
	    	var spliceId="";
	    	for(var i=0;i<users.length;i++){
				if(users[i].id==uIdSocket){
					if(users[i].socketId==socket.id){					
					  	var data={
							query:"update user set online='N' where id='"+users[i].id+"'",
							connection:connection
						}
						spliceId=i;
						helper.queryRunner(data,function(result){
							users.splice(spliceId,1); //Removing single user
							io.emit('exit',users[spliceId]);
						});
					}
				}				
			}

		});
	});
	/*
		Socket event Ends
	*/


	/*
		get to render Home page 
	*/
	
	app.get('/home',function(req, res){
		sessionInfo=req.session;
		if(!sessionInfo.uid){
			res.redirect("/");	
			res.end();	
		}else{
			/*res.redirect('/home#?id='+sessionInfo.uid);*/
			res.render('home');
			res.end();
		}
	});

	/*
		post to handle get_userinfo request
	*/
	app.post('/get_userinfo', function(req, res){
		var data={
			query:"select id,name,p_photo,online from user where id='"+req.body.uid+"'",
			connection:connection
		}
		helper.queryRunner(data,function(result){
			if(result.length>0) {
				var user_info="";			
				result.forEach(function(element, index, array){
					user_info=element;
				});
		    	result_send={
		    		is_logged:true,
		    		data:user_info,
		    		msg:"OK"
		    	};
		    } else {
		    	result_send={
		    		is_logged:false,
		    		data:null,
		    		msg:"BAD"
		    	};
		    }   
		    res.write(JSON.stringify(result_send));
			res.end();
		});
	});

	/*
		post to handle get_msgs request
	*/
	app.post('/get_msgs', function(req, res){
		/*
	    	Calling 'getMsgs' to get messages
	    */
		helper.getMsgs(req.body,connection,function(result){
			res.write(JSON.stringify(result));
			res.end();
		});		
	});

	/*
		post to handle get_recent_chats request
	*/
	app.post('/get_recent_chats', function(req, res){
		/*
	    	Calling 'getUserChatList' to get user chat list
	    */
		helper.getUserChatList(req.body.uid,connection,function(dbUsers){
			res.write(JSON.stringify(dbUsers));
			res.end();
		});	
	});

	/*
		post to handle get_users_to_chats request
	*/
	app.post('/get_users_to_chats', function(req, res){
		/*
	    	Calling 'getUsersToChat' to get user chat list
	    */
		helper.getUsersToChat(req.body.uid,connection,function(dbUsers){
			/*
				Calling 'mergeUsers' to merge online and offline users
			*/
			helper.mergeUsers(users,dbUsers,'yes',function(mergedUsers){
	    		res.write(JSON.stringify(mergedUsers));
	    		res.end();
	    	});			
		});	
	});
	
	app.get('/logout', function(req, res){
		sessionInfo=req.session;
		var uid=sessionInfo.uid;
		
		var data={
			query:"update user set online='N' where id='"+uid+"'",
			connection:connection
		}
		helper.queryRunner(data,function(result){

			req.session.destroy(function(err) {
				if(err) {
			    	console.log(err);
			  	} else {
			  		io.emit('exit',1);
					res.redirect('/');
			  	}

			});
		});
	});
	
}

method.getroutes=function(){
	return this;
}

module.exports = routes;

Till  now completed  following points listed below,

  1.  created helper.js file.
  2. Fetching User's information.
  3. Displaying User's Chat list with current online users.
  4. Sending message unique users .
  5. Showing users available to start a new chat.

And third part we will actually buit the private real time chat.

  • Ladna Meke

    Nice tut. Two questions though:

    What’s the essence of the ‘new Buffer’? Why do we need a buffer? Also, you’ve required the fs module but haven’t used it anywhere.

    • My bad, I forgot to remove fs module I’ll remove that line.

      For ‘new Buffer’ read this:
      http://stackoverflow.com/questions/6182315/how-to-do-base64-encoding-in-node-js

      • Ladna Meke

        Thanks, that link clearly explains what a buffer is. Reinforcement theory, correct me if I’m wrong:

        You’re using the Buffer to produce a base64 encoded URL of the name and id, to pass as query strings. The final outputted url is unique and maps easily to the correct user.

        This begs the question, why use base64 encoded URL? Is it for security reason or something else?

  • Omsun Kumar

    why you have not used mongodb , Pls help me understand ,when we should use mongoDB ,and when we can use Mysql with node js

    • Yeah, actually I wrote this article for beginners to understand how nodejs works, how to use mysql in Nodejs and how to create a basic chat app.

      In upcoming month I will update this article where I will use either MongoDB or RethinkDB.

  • Omsun Kumar

    Can you please provide some article or information ,when to use mongoDB over Mysql with nodejs.
    Please help me understanding this