Как отслеживать количество анонимных пользователей на стороне сервера в Meteor?
Я пишу чувствительное к данным приложение в Meteor и пытаюсь ограничить доступ клиента к максимально возможной информации. Поэтому я хочу реализовать серверную сторону для подсчета количества зарегистрированных и анонимных пользователей.
Я пробовал различные методы. Первый из них был описан в этом вопросе Очистка сервера после отсоединения клиента, что предполагает подключение к нему:
this.session.socket.on("close")
Однако когда я это сделал и попытался сменить коллекцию, он выбросил код "Метеор", который должен всегда выполняться внутри Fiber. Я предполагаю, что эта проблема связана с тем, что после того, как сокет закрыт, этот Fiber убит, поэтому доступ к базе данных невозможен. OP указал на этот код Meteor всегда должен работать в пределах Fiber " при вызове Collection.insert на сервере в качестве возможного решения, но я не был уверен, что это лучший метод, основанный на комментариях к ответу.
Затем я попытался автозапускать переменную:
Meteor.default_server.stream_server.all_sockets().length
но автозапуск никогда не вызывался, поэтому я предполагаю, что переменная не является реактивным контекстом, и я не был уверен, как сделать ее одной.
Последняя идея состояла в том, чтобы сделать стиль keepalive style, но это, похоже, полностью противоречит текстуре "Метеор", и я думаю, что буду использовать только в качестве крайней последней меры.
Я выполнил console.log
функций на this.session.socket
, и единственной возможной функцией была .on("data")
, но это не вызывается, когда сокет закрыт.
Я немного потерял здесь, поэтому любая помощь будет отличной,
Спасибо.
Ответы
Ответ 1
Для полноты, вероятно, лучше всего совместить два ответа выше. Другими словами, сделайте следующее:
Вероятно, это будет канонический способ реализовать это в Метеор. Я создал это как смарт-пакет, который можно установить с помощью Meteorite: https://github.com/mizzao/meteor-user-status
Ответ 2
Благодаря наконечнику Сорхуса мне удалось это решить. Его ответ содержит сердцебиение, которое я хотел избежать. Тем не менее, он содержал трюк использования 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);
}));
}
}
Ответ 3
Оформить проект GitHub howmanypeoplearelooking
Тестирование приложения Meteor, чтобы показать, сколько пользователей сейчас в сети.