I would like to keep track of all clients currently on a page in my app. I am basically implementing something similar to live user list on Google Doc.
A naive approach would be to send a heartbeat to the server at an interval, when a client is on the page.
As an alternative, I am thinking about implementing the following:
But I don't know if that is even feasible. Any ideas or a suggestion for a better solution?
Edit
I would like to only track status of users on a certain page. Therefore meteor-user-status won't suit my needs.
Also I want to track anonymous clients (users who are not logged in)
Your suggested data structure is perfectly reasonable. No need to overthink it!
One slight complication would be that you might have to manually manage your own observeChanges
for the array in the db you are pushing userIds to. That's because meteor publications are not reactive on an $in
query, which I assume you'd use to do something like db.users.find({_id: {$in: arrayOfUsersOnPage}})
.
If you want to avoid that complexity (I know I do) then you could denormalize this information directly to the userDoc. When a user hits a route, you could push a unique ID of the page they're on to an array on their user doc like connectedPages
. Then, your page would just need to subscribe to:
db.users.find({connectedPages: '_id_of_this_page})
which is natively reactive.
Obviously yes, you'd have to manually push/pull the page id to the user document. The easiest way to do that to my mind would be during the and onDestroyed
Template events specific to each page.
Anonymous users gets a little trickier with this second implementation method, as they don't have user documents to denormalize to. If that's a requirement, I'd go with your first idea of a document for each page that contains an array of connected users.
To actually detect when a user loads a given webpage, I would suggest using the onCreated
hook in Blaze or (apparently) the ComponentDidMount
in React. Read more here.
To detect page exit, I have found Meteor's publication onStop
to be reliable. A good discussion can be found here. Others would do this with a simple heartbeat, which I personally find to be very un-Meteor and cumbersome, but reliable.
Regarding how to uniquely identify each user, obviously those logged in will have Meteor.userId()
. For those not logged in, you should rely on Meteor.connection._lastSessionId
which is available only server-side. Update your page document server-side with this list of connected users and then make sure that page is published to all connected clients via the discusson above and you should have the data you need!