I\'m writing a data-sensitive application in Meteor, and am trying to limit the client access to as much information as possible. Therefore, I want to implement server side a wa
Checkout the GitHub project howmanypeoplearelooking
Meteor application test to show how many users are online right now.
For the sake of completeness, it's probably best to combine the two answers above. In other words, do the following:
Meteor.users
, as opposed to a separate collection, as in https://github.com/erundook/meteor-profile-onlineThis would probably be the canonical way to implement this in Meteor. I've created this as a smart package that you can install with Meteorite: https://github.com/mizzao/meteor-user-status
Thanks to Sorhus' tip, I managed to solve this. His answer contains a heartbeat, which I was keen to avoid. However, it contained the trick of using Meteor's "bindEnvironment". This allows access to a collection, which otherwise would not be accessible.
Meteor.publish("whatever", function() {
userId = this.userId;
if(userId) Stats.update({}, {$addToSet: {users: userId}});
else Stats.update({}, {$inc: {users_anon: 1}});
// This is required, because otherwise each time the publish function is called,
// the events re-bind and the counts will start becoming ridiculous as the functions
// are called multiple times!
if(this.session.socket._events.data.length === 1) {
this.session.socket.on("data", Meteor.bindEnvironment(function(data) {
var method = JSON.parse(data).method;
// If a user is logging in, dec anon. Don't need to add user to set,
// because when a user logs in, they are re-subscribed to the collection,
// so the publish function will be called again.
// Similarly, if they logout, they re-subscribe, and so the anon count
// will be handled when the publish function is called again - need only
// to take out the user ID from the users array.
if(method === 'login')
Stats.update({}, {$inc: {users_anon: -1}});
// If a user is logging out, remove from set
else if(method === 'logout')
Stats.update({}, {$pull: {users: userId}});
}, function(e) {
console.log(e);
}));
this.session.socket.on("close", Meteor.bindEnvironment(function() {
if(userId === null || userId === undefined)
Stats.update({}, {$inc: {users_anon: -1}});
else
Stats.update({}, {$pull: {users: userId}});
}, function(e) {
console.log("close error", e);
}));
}
}