最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to track the number of anonymous users server-side in Meteor? - Stack Overflow

programmeradmin3浏览0评论

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 way of counting the number of logged-in, and anonymous, users.

I have tried a variety of methods. The first was as outlined in this question Server cleanup after a client disconnects, which suggests hooking into:

this.session.socket.on("close")

However when I did, and tried to change a collection, it threw a "Meteor code must always run within a Fiber" error. I assume this problem is because once the socket is closed, that Fiber is killed, and so accessing the database is impossible. The OP pointed to this "Meteor code must always run within a Fiber" when calling Collection.insert on server as a possible solution, but I wasn't sure if that's the best method, based on the ments to the answer.

I then tried to autorun on the variable:

Meteor.default_server.stream_server.all_sockets().length

but the autorun never seemed to be called, so I'm assuming that variable is not a reactive context, and I wasn't sure how to make it one.

The last idea was to do a keepalive style thing, but that seems to pletely go against the grain of the Meteor philosophy, and I think I'll only use as an absolute last resort.

I did a console.log of the functions on this.session.socket, and the only other function possible was .on("data"), but this isn't called when the socket is closed.

I'm at a bit of a loss here, so any help would be great, Thanks.

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 way of counting the number of logged-in, and anonymous, users.

I have tried a variety of methods. The first was as outlined in this question Server cleanup after a client disconnects, which suggests hooking into:

this.session.socket.on("close")

However when I did, and tried to change a collection, it threw a "Meteor code must always run within a Fiber" error. I assume this problem is because once the socket is closed, that Fiber is killed, and so accessing the database is impossible. The OP pointed to this "Meteor code must always run within a Fiber" when calling Collection.insert on server as a possible solution, but I wasn't sure if that's the best method, based on the ments to the answer.

I then tried to autorun on the variable:

Meteor.default_server.stream_server.all_sockets().length

but the autorun never seemed to be called, so I'm assuming that variable is not a reactive context, and I wasn't sure how to make it one.

The last idea was to do a keepalive style thing, but that seems to pletely go against the grain of the Meteor philosophy, and I think I'll only use as an absolute last resort.

I did a console.log of the functions on this.session.socket, and the only other function possible was .on("data"), but this isn't called when the socket is closed.

I'm at a bit of a loss here, so any help would be great, Thanks.

Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked Nov 24, 2012 at 18:40 cazgpcazgp 1,5581 gold badge12 silver badges27 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

For the sake of pleteness, it's probably best to bine the two answers above. In other words, do the following:

  • Keep the online status in Meteor.users, as opposed to a separate collection, as in https://github./erundook/meteor-profile-online
  • Keep track of disconnections via callback, instead of a heartbeat, as in https://github./murilopolese/howmanypeoplearelooking

This 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./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 being 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);
    }));
  }
}

Checkout the GitHub project howmanypeoplearelooking

Meteor application test to show how many users are online right now.

发布评论

评论列表(0)

  1. 暂无评论