I am using Sails js 0.11.
Following the tutorial described on the docs here:
I am able to create a pub/sub relationship. However I only want to be notified of "update" events of users that have the field "company=abc". Therefore in the controller I do the following:
subscribe: function(req, res) {
User.find({company:'abc"}).exec(function(e,listOfUsers){
User.subscribe(req.socket,listOfUsers,['create','destroy']);
});
}
This works. However in the case this socket is open, and a new user belonging to this company is created, the socket won't receive notifications for this new user.
In order to solve that, I went to User model, and added:
beforeCreate: function(user, next) {
//just need one sample of user from this company.
//in theory all users of this company are subscribed by same sockets
User.findOne({company:user.company}).exec(function(e,companyUser){
// Get all of the sockets that are subscribed to this user
var subscribers = User.subscribers(companyUser);
// Subscribe them all to this new user
_.each(subscribers, function(subscriber) {
User.subscribe(subscriber.id, user);
});
next();
});
}
However I get the warning
warn: `Model.subscribe()` called by a non-socket request. Only requests originating from a connected socket may be subscribed. Ignoring...
I do not want to create user using sockets. Is there a way around this? Just want to keep my socket subscribers up to date!
Thanks
Actually, putting this in the afterCreate won't really work because the subscriber would receive the message when the object created, but you are putting this after its being created so the event won't run.
However with a trick, we can make this work. Subscribe to the Company instead of the User, here are the details:
So first, subscribe your user to it's company (owner is the company id in my sails app):
Company.findOne({id: req.session.user.owner}).exec(function(e, company) {
Company.subscribe(req.socket, company);
});
Then when you create a User, in the afterCreate, look for the company id in your socket message. Retrieve all of the subscribers of that company, and subscribe them to the "message" context of a User model. Then right after you subscribed all of your user's send a "message" type message to them via the Company model's message() function.
afterCreate: function(message, next) {
Company.findOne({id: message.owner}).exec(function(e, company) {
var subscribers = Company.subscribers(company);
_.each(subscribers, function(subscriber) {
User.subscribe(subscriber, message, 'message');
});
Company.message(company, message.message);
});
next();
},
Here, the message object is the socket.io payload. In the first section where you subscribe your socket client to the company, you can have criteria to specify which user's to subscribe to where, even you can create a specific subscribers criteria table where you store all the different subscription channels.
Hope it helps.
References:
http://sailsjs.org/documentation/reference/web-sockets/resourceful-pub-sub/subscribe
http://sailsjs.org/documentation/reference/web-sockets/resourceful-pub-sub/message