我正在Meteor中编写一个数据敏感的应用程序,并试图限制客户端访问尽可能多的信息。因此,我想实现服务器端计算登录和匿名用户数量的方法。
我尝试了各种方法。第一个是在这个问题Server cleanup after a client disconnects中概述的,它建议挂钩:
this.session.socket.on("close")
然而,当我这样做并尝试更改集合时,它抛出了“Meteor代码必须始终在光纤内运行”错误。我认为这个问题是因为一旦套接字关闭,光纤就会被杀死,因此无法访问数据库。 OP指出这个"Meteor code must always run within a Fiber" when calling Collection.insert on server是一个可能的解决方案,但我不确定这是否是最好的方法,基于对答案的评论。
然后我尝试自动运行变量:Meteor.default_server.stream_server.all_sockets().length
但是自动运行似乎从未被调用过,所以我假设变量不是一个被动的上下文,我不知道如何将它变成一个。
最后一个想法是做一个保持活力的风格的东西,但这似乎完全违背了流星哲学,我想我只会用作绝对的最后手段。
我在console.log
上执行了this.session.socket
个函数,唯一可能的其他函数是.on("data")
,但是在套接字关闭时不会调用它。
我在这里有点亏,所以任何帮助都会很棒, 感谢。
答案 0 :(得分:8)
为了完整起见,最好将上述两个答案结合起来。换句话说,请执行以下操作:
Meteor.users
,而不是单独的集合,如https://github.com/erundook/meteor-profile-online 这可能是在Meteor中实现这一点的规范方法。我已将其创建为智能包,您可以使用Meteorite进行安装:https://github.com/mizzao/meteor-user-status
答案 1 :(得分: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 :(得分:2)
查看GitHub项目howmanypeoplearelooking
流星应用程序测试,以显示现在有多少用户在线。