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

10

我正在使用Meteor编写一个数据敏感型的应用程序,并尽可能限制客户端对信息的访问。因此,我想在服务器端实现一种计算已登录和匿名用户数量的方法。

我尝试了各种方法。第一种是根据这个问题中提到的方式 Server cleanup after a client disconnects,建议连接到:

this.session.socket.on("close")
然而,当我尝试更改集合时,它抛出了一个“Meteor code must always run within a Fiber”错误。我认为这个问题是因为一旦套接字关闭,该Fiber就被杀死了,因此无法访问数据库。 OP指出这个 "Meteor code must always run within a Fiber" when calling Collection.insert on server 可能是一个解决方法,但根据回答的评论,我不确定这是否是最佳方法。
然后我尝试对该变量进行自动运行:
Meteor.default_server.stream_server.all_sockets().length

但是自动运行似乎从未被调用,所以我认为该变量不是反应性上下文,并且我不确定如何使其成为反应性上下文。

最后的想法是做一个保持活动的样式,但这似乎完全违背了Meteor的理念,我认为只有在绝对需要时才会使用它。

我在this.session.socket上进行了console.log函数,唯一可能的其他函数是.on("data"),但当套接字关闭时不会调用此函数。

我有点茫然无措,所以任何帮助都将是巨大的, 谢谢。

3个回答

8
为了完整起见,最好将上面两个答案结合起来。换句话说,按照以下步骤操作: 这可能是在Meteor中实现此功能的规范方式。我已经将其创建为一个智能包,您可以使用Meteorite安装:https://github.com/mizzao/meteor-user-status

虽然这很酷,但文档明确表示它不跟踪匿名用户,因此它并没有真正回答原始问题。 - cazgp
1
自从我写了这篇文章以来,我已经更新了包以跟踪匿名用户。显然,我们无法在Meteor.users中跟踪匿名用户,但是他们的连接都被跟踪。 - Andrew Mao
1
只需要自己做这件事。使用 @AndrewMao 的 mizzao:meteor-user-status 包,获取匿名用户数量就像查询内存中的 UserStatus.connections 集合一样容易,查询没有 userId 的连接即可... UserStatus.connections.find({userId: {$exists: false}}).count() - evolross

3

感谢Sorhus的提示,我成功解决了这个问题。他的答案包含一个心跳,而我很想避免这种情况。然而,它包含了使用Meteor的“bindEnvironment”的技巧。这允许访问一个否则无法访问的集合。

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);
    }));
  }
}

2

请查看 GitHub 项目howmanypeoplearelooking

这是一个 Meteor 应用程序测试,用于显示当前有多少用户在线。


这只是一个恶作剧。我已经下载了代码(Dumbs = new Meteor.Collection("dumbs"); :) ) - Matanya
@Matanya:Dumbs只是一个幼稚的集合名称,但应用程序可以正常工作 - Dan Dascalescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接