Skip to content

Commit

Permalink
Use a presence collection so we can track non-logged in users.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeasday committed Mar 6, 2013
1 parent 37e9308 commit 31a2004
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0 -- moved over to a presence collection so we could track more than one presence per user and presences of non-logged in users
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ $ mrt add presence

## Usage

By default, the package will, every second, track that a user is online. If it hasn't seen a user online within the last 10 seconds, it assumes they are offline.
By default, the package will, every second, track a _browser window_'s activity. If it hasn't seen activity from a window in 10 seconds, it will assume that window is offline.

The user's online state can be tracked via `user.presence.state`, which is set to `'online'` if they are online.
The user's online state can be tracked via the `Meteor.presences` collection, referenced by `userId`

NOTE: The package doesn't publish the presence field of any users, you'll need to do something like
NOTE: The package doesn't publish the presences by default, you'll need to do something like
```js
Meteor.publish('userPresence', function() {
// Setup some filter to find the users your logged in user
// cares about. It's unlikely that you want to publish the
// presences of _all_ the users in the system.
var filter = {};

return Meteor.users.find(filter, fields: {'presence.state': true});
return Meteor.presences.find(filter);
});
```

To use that presence, you can inspect the `Meteor.presences` collection in the client.

## Advanced Usage

If you want to track more than just what a user is doing (but instead what they are up to), you can set a custom state function. (The default state function return just `'online'`):
Expand All @@ -41,4 +43,8 @@ Meteor.Presence.state = function() {
}
```

Of course presence will call your function reactively, so everyone will know as soon as things change.
Of course presence will call your function reactively, so everyone will know as soon as things change.

## Contributing

Please! The biggest thing right now is figuring how to write tests.
1 change: 1 addition & 0 deletions package.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Package.describe({
});

Package.on_use(function (api) {
api.add_files('presence_common.js', ['client', 'server']);
api.add_files('presence_client.js', 'client');
api.add_files('presence_server.js', 'server');
});
7 changes: 5 additions & 2 deletions presence_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ PRESENCE_INTERVAL = 1000;
// The user will be decorated with the state, which will be reset to null
// when they close the browser tab or log off
Meteor.Presence = {
state: function() { return 'online'; }
state: function() { return 'online'; },
// we get told about the sessionId by the server, track it here so we
// overwrite the correct thing
sessionId: Meteor.uuid()
}

Meteor.setInterval(function() {
Expand All @@ -19,6 +22,6 @@ Meteor.autorun(function() {
// read this, so the context is invalidated every time the interval changes
Session.get('last-presence-set-at');

Meteor.call('setPresence', Meteor.Presence.state());
Meteor.call('setPresence', Meteor.Presence.sessionId, Meteor.Presence.state());
});

1 change: 1 addition & 0 deletions presence_common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Meteor.presences = new Meteor.Collection('presences');
29 changes: 14 additions & 15 deletions presence_server.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
PRESENCE_TIMEOUT_MS = 10000;
PRESENCE_INTERVAL = 1000;



// a method to indicate that the user is still online
Meteor.methods({
setPresence: function(state) {
if (Meteor.userId()) {
Meteor.users.update(Meteor.userId(), {$set: {presence: {
state: state,
lastSeen: new Date()
}}});
}
setPresence: function(sessionId, state) {
Meteor.presences.update({
sessionId: sessionId
}, {$set: {
userId: Meteor.userId(),
state: state,
lastSeen: new Date()
}}, {
upsert: true
});
}
});

Meteor.setInterval(function() {

// set all users who we haven't seen for a while to not be present
var match = {
'presence.lastSeen': {$lt: new Date(new Date().getTime() - PRESENCE_TIMEOUT_MS)},
'presence.state': {$exists: true}
};

Meteor.users.update(match, {$unset: {'presence.state': true}});
var since = new Date(new Date().getTime() - PRESENCE_TIMEOUT_MS);
Meteor.presences.remove({lastSeen: {$lt: since}});
}, PRESENCE_INTERVAL);
2 changes: 1 addition & 1 deletion smart.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"description": "A package to help track users' presence",
"homepage": "https://github.com/tmeasday/meteor-presence",
"author": "Tom Coleman",
"version": "0.0.1",
"version": "0.1.0",
"git": "https://github.com/tmeasday/meteor-presence.git"
}

0 comments on commit 31a2004

Please sign in to comment.