i am trying to create a real time app using sailsjs. i saw tutorials on youtube, searched for simple solution on there site. searched github for simple example running example. i found some working but are older version. whatever i learned and found i tried to implement in my app.
that is sessionController.js
var bcrypt = require('bcrypt');
module.exports = {
'login':function (req, res) {
if (req.isSocket) {
return res.json({status: 403, redirectTo: "/sess/new"});
} else {
res.view('sess/new');
}
},
'create': function (req,res, next) {
if (!req.param('email') || !req.param('password')) {
var usernamePasswordRequiredError = [{name : 'usernamePasswordRequired', message:'You must enter both username and password'}]
req.session.flash ={
err: usernamePasswordRequiredError
}
res.redirect('/session/login');
return;
}
User.findOneByEmail(req.param('email'), function (err, user) {
if (err) return next(err);
if (!user) {
var noAccountError = [{name:'noAccount', message:'The email address '+req.param('email')+' not found'}];
req.session.flash = {
err:noAccountError
}
res.redirect('/session/login');
return;
};
bcrypt.compare(req.param('password'), user.password, function (err, valid) {
if (err) return next(err);
if (!valid) {
var usernamePasswordMismatchError = [{name:'usernamePasswordMismatch', message:'Invalid username and password combination'}]
req.session.flash = {
err: usernamePasswordMismatchError
}
res.redirect('/session/login');
return;
};
req.session.authenticated = true;
req.session.User = user;
user.online = true;
user.save(function (err,user) {
if (err) return next(err);
// Inform other sockets (e.g. connected sockets that are subscribed) that this user is now logged in
console.log('loged in publishUpdate');
User.publishUpdate(user.id, {
loggedIn: true,
id: user.id,
name: user.fillname,
action: ' has logged in.'
});
if (req.session.User.admin) {
res.redirect('/user');
return;
};
});
res.redirect('/user/');
});
});
},
'logout':function (req, res, next) {
User.findOne(req.session.User.id, function foundUser (err, user) {
var userId = req.session.User.id;
User.update(userId,{
online:false
}, function (err) {
if (err) return next(err);
// Inform other sockets (e.g. connected sockets that are subscribed) that the session for this user has ended.
User.publishUpdate(userId, {
loggedIn: false,
id: userId,
name: user.fullname,
action: ' has logged out.'
});
req.session.destroy();
return res.redirect('/session/login');
});
});
}
};
That is userController.js
module.exports = {
'signup':function (req, res) {
if (req.isSocket) {
return res.json({status: 403, redirectTo: "/user/signup"});
} else {
res.view();
}
},
'create': function (req, res, next) {
console.log("got sothing "+req.param('fullname'));
//"req: "+req.param('fullname')
var params = {
'fullname' : req.param('fullname'),
'username' : req.param('username'),
'email' : req.param('email'),
'password' : req.param('password')
};
User.create( params,function userCreated(err, user) {
if (err) {
req.session.flash = {
err:err
}
return res.redirect('/user/signup');
}
req.session.authenticated = true;
req.session.User = user;
user.online = true;
user.save(function (err, user) {
if (err) return next(err);
User.publishCreate(user);
res.redirect('/user/show/'+user.id);
});
});
},
'update': function (req, res, next) {
var id = req.param('id');
var params = {
'fullname' : req.param('fullname'),
'username' : req.param('username'),
'email' : req.param('email')
};
User.update(req.param('id'), req.params.all(), function userUpdated(err, user) {
if(err){
return res.redirect('/user/edit/'+id);
} //return// next(err);
User.publishUpdate(user);
res.redirect('/user/show/'+id);
});
},
'show':function (req, res, next) {
var id = req.param('id');
User.findOne(req.param("id"), function foundUser (err, user) {
if(err) return next(err);
if(!user) return next();
User.publishUpdate(user);
res.view({
user:user
});
});
},
'index':function (req, res, next) {
User.find(function foundUsers (err, users) {
if(err) return next(err);
if (req.isSocket) {
return res.json({status: 403, redirectTo: "/user"});
} else {
res.view({
users:users
});
}
});
},
'edit':function (req, res, next) {
console.log("got sothing "+req.param('id'));
var id = req.param('id');
User.findOne(req.param("id"), function foundUser (err, user) {
if(err) return next(err);
if(!user) return next('User does\'t exist.');
res.view({
user:user
});
});
},
destroy :function (req, res, next) {
User.findOne(req.param('id'), function foundUser (err, user) {
if (err) return next(err);
if (!user) return next('User does\'t exist.');
User.destroy(req.param('id'), function userDestroyed (err) {
if (err) return next(err);
//publish
User.publishUpdate(user.id, {
name: user.fullname,
action: ' has been destroyed.'
});
// Let other sockets know that the user instance was destroyed.
User.publishDestroy(user.id);
});
res.redirect('/user');
});
},
'subscribe':function (req, res) {
User.find(function foundUsers (err, users) {
User.subscribe(req.socket, users);
res.send(200);
});
}
};
AND that is app.js to receive data
io.socket.on('connect', function messageReceived() {
console.log(this.socket.sessionid);
this.socket.on('message', function (tmessage) {
console.log(tmessage);
this.socket.get('/user/subscribe');
});
});
problem is simple i am not getting response when user signup or signout or on anything user do. i think i am publishing actions correctly but don't know about receiving.
it will be really very helpful if some one can point me on right direction. i can share more info if needed.
i am going to share this on github . so it will be help full for others.
thanks.
Have you read the official documentation for resourceful pub-sub? One of the first things it states is that you should be listening to events named after the model--so if you want to hear about things happening to your User
model, you need to do:
io.socket.on('user', ...)
not
io.socket.on('message', ...)
Second, as Jason mentions above, you need to subscribe your socket to the instances you want to receive notifications about. You can do that with your custom subscribe
action, but if you have REST blueprints turned on (the default) then that action isn't really necessary; just doing
io.socket.get('/user', function(data){} )
will subscribe the requesting socket to all of the returned User
instances. See the docs for blueprint .find() for more info. This call doesn't need to appear before the io.socket.on
call, but it can't appear inside the handler as it will then never be called. So you can rewrite your client-side code as:
io.socket.on('connect', function socketConnected() {
console.log(this.socket.sessionid);
// Respond to user events. You can always safely use the
// global `io.socket` to bind event handlers
io.socket.on('user', function (tmessage) {
console.log(tmessage);
});
// Get the users and just spit them out to the console. This will also
// subscribe the socket to any events involving the returned users, which
// will then be handled by the `io.socket.on` code above.
io.socket.get('/user', console.log.bind(console));
});
For a good demo of various socket methods at work, see the SailsChat sample application.
Your app.js
code seems to imply that you hit the subscribe
action when it receives a message from the socket.
...
this.socket.on('message', function (tmessage) {
console.log(tmessage);
this.socket.get('/user/subscribe');
});
...
That's probably why its failing because the socket has not been associated with the collection yet, and so it wont receive any messages. Try moving the socket subscribe call outside of the message handler.
...
this.socket.get('/user/subscribe');
this.socket.on('message', function (tmessage) {
console.log(tmessage);
});
...