简体   繁体   English

如何跟踪Meteor中匿名用户服务器端的数量?

[英]How to track the number of anonymous users server-side in Meteor?

I'm writing a data-sensitive application in Meteor, and am trying to limit the client access to as much information as possible. 我正在Meteor中编写一个数据敏感的应用程序,并试图限制客户端访问尽可能多的信息。 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. 但是,当我这样做,并试图更改集合时,它抛出了“Meteor代码必须始终在光纤内运行”错误。 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 comments to the answer. 当在服务器上调用Collection.insert作为可能的解决方案时,OP指出这个“Meteor代码必须始终在光纤内运行” ,但我不确定这是否是最好的方法,基于对答案的评论。

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 completely go against the grain of the Meteor philosophy, and I think I'll only use as an absolute last resort. 最后一个想法是做一个keepalive风格的东西,但这似乎完全违背了流星哲学,我想我只会用作绝对的最后手段。

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. 我在this.session.socket上做了一个console.log函数,唯一可能的其他函数是.on("data") ,但是当套接字关闭时不会调用它。

I'm at a bit of a loss here, so any help would be great, Thanks. 我在这里有点亏,所以任何帮助都会很棒,谢谢。

For the sake of completeness, it's probably best to combine the two answers above. 为了完整起见,最好将上面的两个答案结合起来。 In other words, do the following: 换句话说,执行以下操作:

This would probably be the canonical way to implement this in Meteor. 这可能是在Meteor中实现这一点的规范方法。 I've created this as a smart package that you can install with Meteorite: https://github.com/mizzao/meteor-user-status 我已将其创建为可以使用Meteorite安装的智能包: https//github.com/mizzao/meteor-user-status

Thanks to Sorhus' tip, I managed to solve this. 感谢Sorhus的提示,我设法解决了这个问题。 His answer contains a heartbeat, which I was keen to avoid. 他的回答包含一个心跳,我很想避免。 However, it contained the trick of using Meteor's "bindEnvironment". 但是,它包含使用Meteor的“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);
    }));
  }
}

Checkout the GitHub project howmanypeoplearelooking 查看GitHub项目howmanypeoplearelooking

Meteor application test to show how many users are online right now. 流星应用程序测试,以显示现在有多少用户在线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM