How to get response from socket.on before calling socket.emit - node.js

I am using node.js for creating an application that is maintaing the repository for the courses and its respective lectures and slides. And the retreival of courses of student (from mysql Db) is based on student name, the retreival of lectures is based on course name and soo on. The student name is stored on server and i must get it before calling server for getting course list.
Here is my code with more explanation:
var StdName;
$(document).ready(function () {
//connect to server
connectBind();
var socket = $("#click").data();
/**********Query database For student name!!!**********/
try {
socket.emit('askStdName');
}
catch (err) {
alert(err.message);
}
/********Query database For Courses!!!************/
try {
socket.emit('view-contents', StdName);
}
catch (err) {
alert(err.message);
}
});
//connecting to server
function connectBind() {
// connect to server on this port.
var socket = io.connect('http://localhost:3000');
$("#click").data(socket);
/**********GETTING NAME OF STUDENT*********/ //I WANT TO GET STUDENT NAME BEFORE THE QUERY FOR COURSES GET CALLED
try {
socket.on('get-Studentname', function (data) {
StdName = data;
alert("StdName: " + StdName);
});
}
catch (err) {
alert(err.Message);
}
And here is the server side script:
var express = require('express'); //load express
var http = require('http'); // then http
var socketIO = require('socket.io'); // then socket
var mysql = require('mysql');
var nodemailer = require("nodemailer");
var client = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'smartboard_db'
});
client.connect();
var app = express(); // create application
var server = http.createServer(app); //create server
var io = socketIO.listen(server); // start listening to server.
io.set('log level', 2);
// setup routing for static files.
app.use(express.static(__dirname + '/public'));
//start server
server.listen(3000, function(){
console.log('Server running...');
});
// First page
app.get('/', function(request, response) {
response.sendfile(__dirname + '/student-home.html');
});
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
var sucess;
console.log("client connected");
/************SENDING THE NAME TO CLIENT*************/
socket.on('askStdName', function () {
console.log('sending student name to client');
socket.emit('get-Studentname', stdName);
});
/***********CHANNEL FOR GETTING COURSE LIST************/
socket.on('view-contents', function (stdName) {
//console.log("this is what I get from client for courses: " + stdName);
var DATABASE = 'smartboard_db';
client.query('USE ' + DATABASE);
/*****QUEURY FOR COURSES *****************/
client.query('SELECT courses FROM student_info WHERE name = "' + stdName + '"', function (err, results) {
if (err) {
throw err;
}
else {
console.log(JSON.stringify({ courses: results }));
socket.emit('courses', JSON.stringify({ courses: results }));
}
});
});
});
Can ny one help please?

If the get-Studentname event should always be followed by getting the courses:
// request student name
socket.emit('askStdName');
// wait for the student name to be returned, followed by requesting the courses
socket.on('get-Studentname', function (StdName) {
socket.emit('view-contents', StdName);
});
Alternatively, you can pass a function with the request for the student name, which the server can call to send back the response (instead of having the server emit a response). This does require a different setup on your server though:
// client code
socket.emit('askStdName', function(StdName) {
socket.emit('view-contents', StdName);
});
// server code should look like this:
socket.on('askStdName', function(done) {
// get student name (depends on your setup)
...
// call the function to return the value
done(StdName);
});

Related

private chat with socket.io

I'm having trouble with my chat app, I need to be able to send a private message to a specific user, I was able to select that specific user but for some reason couldn't figure out how to send the private message.
Below you will find the code for my server, please help:
var express = require('express');
var app = express();
var PORT = process.env.PORT || 8000;
var http = require('http').Server(app); // this is a node server that uses express as the boiler plate
var io = require('socket.io')(http); // socket! pass our server as a parameter to it
// use express static to expose a folder
app.use(express.static(__dirname + '/public'));
var users = [],
connections = [];
var onlineClients = {};
// Register events on socket connection
io.on('connection', function(socket){
connections.push(socket);
// console.log("connected socket", connections);
socket.on("disconnect", function() {
users.splice(users.indexOf(socket.username), 1);
updateUsernames();
connections.splice(connections.indexOf(socket), 1);
console.log("disconnected socket", connections.length)
});
socket.on("send message", function(data) {
// console.log(data);
io.emit("new message", {msg: data, user: socket.username});
});
socket.on("notify user", function(data) {
io.emit("notify user", {user: socket.username})
});
socket.on("new user", function(data) {
socket.username = data;
users.push(socket.username);
updateUsernames();
});
function updateUsernames() {
io.emit("get users", users);
};
socket.on("private", function(data, recipientName) {
var recipient = connections.filter(function (recipient) {
return recipient.username === recipientName;
})[0];
console.log(recipient.id);
console.log(data);
io.sockets.socket(recipient.id).emit("received private msg", data);
});
// socket.on("create room", function(room) {
// socket.join(room);
// io.sockets.in(room).emit('event', "hey wusup am in this room");
// console.log(socket);
// })
});
http.listen(PORT, function(){
console.log('Server started on port ' + PORT);
});
First add user in chat room so that will easy to find a user in your private chat room
Your client side code for join private room
<input type="text" class="form-control" id="user_email" placeholder="user_email" />
<button text="join room" class="btn btn-primary btn-block" onclick="a();"> Join Room</button>
your javascript code in client side
function a(){
io.emit('privatechatroom', {email:document.getElementById('user_email').value});
}
your server side code to add user in your room
socket.on('privatechatroom',function(data){
socket.join(data.email);
io.emit('res',{mes:"you are added"})
});
now u can send private message to that person that is recently addedd to this room
client side
function b() {
io.emit('sendmail', { email: document.getElementById('sender_mail').value, message: document.getElementById('message').value });
$('#message').val('');
}
/*serverside code*/
socket.on('sendmail', function (data) {
io.sockets.in(data.email).emit('new_msg', { msg: data.message });
console.log(data.email);
});
Here is the clear solution of mine for your question...
Send a message to Particular client(Private chat)
I hope it will work for you sue..

Why does not sending data io.sockets.emit and socket.broadcast.emit

Tried different methods, but the data is sent to a maximum of one or two clients. How to send data to all the clients connected to the server ? What am I doing wrong?
Server.js:
var PORT = 3000;
var options = {
// 'log level': 0
};
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server, options);
server.listen(PORT);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/attantions/templates/.default/template.php');
});
io.sockets.on('connection', function (client) {
client.on('attantion', function (data) {
try {
// Tried so
io.sockets.volatile.emit('attantion', data);
// And tried so
io.sockets.emit('attantion', data);
client.emit('attantion', data);
client.broadcast.emit('attantion', data );
} catch (e) {
console.log(e);
client.disconnect();
}
});
});
Client.js:
socket.emit("attantion", data);
socket.on('attantion', function (data) {
pushData(data);
});
See this post for different options for socket.io messages
Send response to all clients except sender (Socket.io)
io.sockets.on('connection', function (client) {
client.on('attantion', function (data) {
//client.emit('attantion', data ); // This will send it to only the client
//client.broadcast.emit('attantion', data); // This will send it to everyone but this client
io.emit('attantion', data); // This will send it to all attached sockets.
});
});
Edit
I wonder if this post can help you?
Socket.io - Cannot load file
I was curious how sending the php file to the client through node.js works? are you using another framework?
Could you show more of what your client code looks like? loading the lib and the instantiation of the socket.

Multiply io.on("connection")

After every page updating I have +1 socket connection..
module.exports = function(io, client) {
var GameController = {
gamePage: function(req, res) {
client.hget('games', 'game.' + req.params.id, function (err, result) {
if (err) return result(err);
var game = JSON.parse(result);
io.on('connection', function (socket) {
console.log('send');
console.log(socket.id);
io.emit('get_bets', game.players);
});
res.render('pages/game', {
title: 'Game - ' + req.params.id,
user: req.user,
game: game
});
});
};
return GameController;
});
route file:
module.exports = function(io, client) {
var express = require('express');
var router = express.Router();
var GameController = require('controllers/GameController')(io, client);
router.get('/:id', GameController.gamePage);
...
return router;
};
Client side on react:
var Game = React.createClass({
getInitialState: function() {
this.socket = io();
return {
bets: null
}
},
socketGetBets: function() {
var that = this;
this.socket.on('get_bets', function(data) {
console.log('get bets');
that.setState({ bets: data });
});
this.socket.on('rand', function(data) {
console.log(data);
});
},
...
But after debug I find what problem not in client side.
app.js file:
var socket_io = require('socket.io');
var io = socket_io();
app.io = io;
//route
var game = require('./routes/games')(io, client);
bin/www file:
var server = http.createServer(app);
var io = app.io;
io.attach( server );
After page updating, io.on("connection") event show me "send" message in console, after second page updating, I have "send" "send", third update - "send" "send" "send" etc. Than Memory leak warning appeared. Console log socked.id show the same value many time.
Every time you call on, whether it's io.on or socket.on, you are registering an event handler. This being the case, you probably don't want to be calling io.on('connection') inside of a route, as you will register a new connection handler every time that route is accessed. This is why you are seeing cumulative messages being logged in the console.
In fact, you probably don't want to mix express routing with socket functions at all, as they are different protocols and will work independent of each other.
// server side
// this should only be called once per connection.
io.on('connection', function (socket) {
// handle socket protocol stuff.. fetching server data, sending data
socket.on('fetch bets', function() {
// get game.players from server
// updating other sockets
io.emit('get_bets', game.players);
})
})
app.get('/route', function (req, res) {
// handle http protocol stuff.. fetching server data, sending data
// send data back to caller
res.json(data)
})
The same applies to socket.on in your client side. It looks like you're adding a new 'get_bets' event handler everytime you call socketGetBets.
Instead you probably want to register that event handler one single time, likely in componentDidMount or componentWillMount. Also, because a socket connection can be considered global for your application, you can create the connection above your app.
// client side
var socket = io()
var Game = React.createClass({
getInitialState: function() {
return {
bets: null
}
},
componentWillMount: function() {
var that = this
socket.on('get_bets', function(data) {
that.setState({ bets: data })
})
}
...

Message broadcasted multiple times in Socket.io

I am relatively new to node.js and socket.io. While building a sample chat room application I am encountering a case where when I refresh the browser n times, and then send a message, the message gets broadcasted n-times to all the clients. How do I make it not broadcast multiple times and just once? Here goes the server side and client side code.
qaserver.js
var express = require('express')
, app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server, { log : false });
server.listen(4040);
var redis = require('redis');
var r43 = redis.createClient('6379', '127.0.0.1');
r43.select("43");
// Set the view directory to /views
app.set("views", __dirname + "/views");
app.use(express.static(__dirname + '/public'));
// Let's use the Jade templating language
app.set("view engine", "jade");
app.get("/", function(request, response) {
response.end("Welcome to the homepage!");
});
app.get("/qaclient", function(request, response) {
response.render("qaclient", { message: "Welcome to QA Forum" });
io.sockets.once('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(){
// store the username in the socket session for this client
socket.join('test_room');
socket.room='test_room';
console.log("------------- List of connected clients on adduser -------------------");
var clients = io.sockets.clients('test_room'); //
console.log(clients);
//socket.username = username;
socket.emit("welcome_fn",socket.room);
// echo to client they've connected
});
socket.on('message', function (data) {
//io.sockets.in(socket.room).emit('broadcast_message', data.name,data.message);
console.log("------------- List of connected clients on message broadcast -------------------");
var clients = io.sockets.clients('test_room'); //
console.log(clients);
socket.broadcast.to('test_room').emit('broadcast_message', data.name,data.message);
//io.sockets.emit('broadcast_message', data.name,data.message);
console.log(data.name);
console.log(data.message);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
console.log('Socket disconnected : ');
console.log(socket.room);
socket.leave('test_room');
//console.log(socket.leave(socket.room));
});
});
});
--
qaclient.js
window.onload = function() {
var messages = [];
var field = document.getElementById("message");
sendButton = document.getElementById("sendbutton");
//var content = document.getElementById("content");
var name = document.getElementById("name");
var socket = io.connect('http://localhost:4040');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser');
});
socket.on('welcome_fn',function(room)
{
chatcontent.innerHTML = "<b>Welcome to Chat central.. Type your message to start chatting in room "+ room +"</b>";
});
socket.on('broadcast_message', function (name,message) {
var data=new Object();
data.message=message;
data.username=name;
if(message) {
messages.push(data);
var html = '';
console.log(messages.length);
for(var i=0; i<messages.length; i++) {
html += '<b>' + messages[i].username + ': </b>';
html += messages[i].message + '<br />';
}
chatcontent.innerHTML = html;
}
//socket.emit('message', { name: name; message:field });
});
sendButton.onclick = function() {
if($.trim(field.value)=="")
{
alert("Enter the message Foo!");
}
else
{
name_tosend_tmp=name.value;
name_tosend= name_tosend_tmp.replace(/(<([^>]+)>)/ig,"");
message_tosend_tmp=field.value;
message_tosend= message_tosend_tmp.replace(/(<([^>]+)>)/ig,"");
socket.emit('message', { name: name_tosend , message:message_tosend });
var data=new Object();
data.message=message_tosend;
data.username=name_tosend;
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + messages[i].username + ': </b>';
html += messages[i].message + '<br />';
}
chatcontent.innerHTML = html;
document.getElementById("name").value="";
document.getElementById("message").value="";
}
}
}

Express in server to perform a database query

I want to know how ExpressJS works in the server side
I need some information on Server side, Main things are,As per my knowledge,
ExpressJS can perform all the functionalists of a PHP - - - IS it
true ?
My Client(Android) is ready to submit a POST request to Server
If i can send one single information in the form of (Key,value) pair,
can the Express accept that pair- - Identify the value based on key
and, to perform a sql query to Database based on the value received
from android client?
If it can how it does it?
MY Express Program ( It gives a Response without scenario explained above - How to modify this program )
var express = require('express')
, async = require('async')
, http = require('http')
, mysql = require('mysql');
var app = express();
var connection = mysql.createConnection({
host: 'localhost',
user: '*********',
password: "*****",
database: 'DB'
});
connection.connect();
// all environments
app.set('port', process.env.PORT || 7002);
//
//REQUEST FOR FIRST REQUEST
//
app.get('/',function(request,response){
var name_of_restaurants, RestaurantTimings;
async.series( [
// Get the first table contents
function ( callback ) {
connection.query('SELECT * FROM restaurants', function(err, rows, fields)
{
console.log('Connection result error '+err);
name_of_restaurants = rows;
callback();
});
},
// Get the second table contents
function ( callback ) {
connection.query('SELECT * FROM RestaurantTimings', function(err, rows, fields)
{
console.log('Connection result error '+err);
RestaurantTimings = rows;
callback();
});
}
// Send the response
], function ( error, results ) {
response.json({
'restaurants' : name_of_restaurants,
'RestaurantTimings' : RestaurantTimings
});
} );
} );
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Hope I am clear
Thanks ,
You can send information via query params or as part of the url path. If you send it as a query param, you can access it using
req.query.keyName;
If you want to send the value as part of the url, you'll have to add a route to accept it. You can accept variable content in a url by using the :keyName form. Express will capture it in req.params. So it would look a little like this:
app.get('/some/url/:keyName', function(req, res, next){
var keyName = req.params.keyName;
// . . .
});
Then you can send your http request to '/some/url/someKeyValue' and the variable keyName will then be equal to whatever you add after /some/url/.
If you're POSTing data in the body of the request, access it with req.body.keyName.
EDIT: Here's an attempt at using the original code. Note that I'm still making up values and guessing at what the intent is.
var express = require('express')
, async = require('async')
, http = require('http')
, mysql = require('mysql');
var app = express();
var connection = mysql.createConnection({
host: 'localhost',
user: '*********',
password: "*****",
database: 'DB'
});
connection.connect();
// all environments
app.set('port', process.env.PORT || 7002);
//
//REQUEST FOR FIRST REQUEST
//
app.get('/',function(request,response){
var name_of_restaurants, RestaurantTimings;
async.series( [
// Get the first table contents
function ( callback ) {
connection.query('SELECT * FROM restaurants WHERE name = ' . request.body.name, function(err, rows, fields) {
console.log('Connection result error '+err);
name_of_restaurants = rows;
callback();
});
},
// Get the second table contents
function ( callback ) {
connection.query('SELECT * FROM RestaurantTimings', function(err, rows, fields) {
console.log('Connection result error '+err);
RestaurantTimings = rows;
callback();
});
}
// Send the response
], function ( error, results ) {
response.json({
'restaurants' : name_of_restaurants,
'RestaurantTimings' : RestaurantTimings
});
} );
} );
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
But you should really not query directly like that because of SQL injection. I've never used MySQL from node, but I'm sure there is some way to use parameterized queries. Hope this is more helpful.
Also, I'm assuming that the data will be passed in the request body, since you said you are ready to POST to the server.

Resources