0

We are building a chat application and are currently working on a system to see all the users in a given room.

We have a Mongo Document set up with an array of active_users where we will push and pull user names to in order to keep track of the online users. We have come to the conclusion that realizing a user has connected to a given room is fairly simple. All we need to do is in the router, when a user accesses the page, we push that user's name into the document.

Now the tricky part is realizing when that user has left that given page? Obviously jQuery isn't a reliable option, so how do we know when a user's connection to a specific page is broken?

Scalahansolo
  • 2,615
  • 6
  • 26
  • 43
  • 3
    possible duplicate of [Server cleanup after a client disconnects](http://stackoverflow.com/questions/10257958/server-cleanup-after-a-client-disconnects) – jacksondc Jun 24 '14 at 21:17
  • The [chatroom code for CrowdMapper](https://github.com/mizzao/CrowdMapper/blob/master/server/chat_server.coffee) is basically doing most of what you're asking for already. – Andrew Mao Jun 25 '14 at 15:14

3 Answers3

0

You could do this:

Meteor.publish("page", function() {
    this._session.socket.on("close", function() { 
        //Change your active users here
    });
});

and for your page that you track

Meteor.subscribe('page');

I use this in the analytics package on atmosphere

Tarang
  • 75,157
  • 39
  • 215
  • 276
0

There's an Atmosphere package called Presence that does exactly what you need.

Some extra details from the README about keeping track of custom states...

State functions

If you want to track more than just users' online state, you can set a custom state function. (The default state function returns just 'online'):

// Setup the state function on the client
Presence.state = function() {
  return {
    online: true,
    currentRoomId: Session.get('currentRoomId')
  };
}

Now we can simply query the collection to find all other users that share the same currentRoomId

Presences.find({ state: { online: true, currentRoomId: Session.get('currentRoomId') } })

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

JShimko
  • 106
  • 6
  • Would this work for if I wanted to store a set of rooms that a the user is currently in? I.e. A user is in 5 rooms at the same time, and I want to know all of the rooms they are in. – Scalahansolo Jun 25 '14 at 14:37
0

Meteor has connection hooks so you can run a function when the user disconnects from the server. Setting the onClose() callback inside a method called by the client will allow you to close the userId in the function.

Code on the server could be like this:

Meteor.methods({
  joinRoom: function( roomId ){
    var self = this;
    Rooms.update( {roomId: roomId}, {$push:{userId: self.userId}});

    self.connection.onClose( function(){
      Rooms.update( {roomId: roomId}, {$pull:{userId: self.userId}})
    });    
  }
});
user728291
  • 4,138
  • 1
  • 23
  • 26
  • I dont think this is going to work because this will only handle if the user is online, not exactly which rooms the user is actively in. – Scalahansolo Jun 25 '14 at 14:38
  • Aren't you able to call a method ( maybe from the router ) each time a user changes or leaves a room? If you can maintain the list of rooms they are in while active then also maintain an onClose() function to remove them when they go offline. I didn't mean to write a complete solution just a basic example of the functionality. – user728291 Jun 26 '14 at 08:41