2012-11-24 15 views
10

Piszę aplikację wrażliwą na dane w Meteor i próbuję ograniczyć dostęp klienta do jak największej ilości informacji. Dlatego chcę wdrożyć stronę serwerową w sposobie liczenia liczby zalogowanych i anonimowych użytkowników.Jak śledzić liczbę anonimowych użytkowników po stronie serwera w Meteorze?

Próbowałem różnych metod. Pierwszym był podanych w pytaniu Server cleanup after a client disconnects, co sugeruje, spinanie do:

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

Jednak kiedy ja, i próbował zmienić kolekcję, to wyrzucił „kod Meteor musi zawsze działać w Fibre” błąd. Zakładam, że ten problem polega na tym, że po zamknięciu gniazda, że ​​Fibre jest zabity, a więc uzyskanie dostępu do bazy danych jest niemożliwe. OP wskazał na to "Meteor code must always run within a Fiber" when calling Collection.insert on server jako możliwe rozwiązanie, ale nie byłem pewien, czy jest to najlepsza metoda, oparta na komentarzach do odpowiedzi.

Potem próbował autorun na zmienną:

Meteor.default_server.stream_server.all_sockets().length 

autorun ale nigdy nie wydawało się nazywać, więc jestem przy założeniu, że zmienna nie jest reaktywny kontekst, i nie byłem pewien, jak uczyń to jednym.

Ostatnim pomysłem było wykonanie stylu utrzymaniowego, ale wydaje się, że jest to całkowicie sprzeczne z filozofią Meteorytów i myślę, że użyję go jako absolutnej ostateczności.

Zrobiłem funkcji na this.session.socket, a jedyną inną możliwą funkcją było .on("data"), ale nie jest to wywoływane, gdy gniazdo jest zamknięte.

Jestem tu trochę przegrany, więc każda pomoc będzie świetna, Dzięki.

Odpowiedz

8

W celu uzupełnienia, prawdopodobnie najlepiej jest połączyć dwie powyższe odpowiedzi. Innymi słowy, należy wykonać następujące czynności:

Prawdopodobnie byłby to kanoniczny sposób wdrożenia tego w Meteorrze. Stworzyłem to jako inteligentny pakiet, który można zainstalować z Meteorytem: https://github.com/mizzao/meteor-user-status

+0

Nie mogę ci wystarczająco podziękować za to :) – Pawan

+0

Podczas gdy jest to bardzo fajne, doktorzy wyraźnie mówią, że nie śledzi użytkowników anon, więc nie odpowiada na oryginalne pytanie. – cazgp

+1

@ cazgp Odkąd napisałem ten post, zaktualizowałem pakiet, aby śledzić anonimowych użytkowników. Oczywiście nie możemy śledzić anonimowych użytkowników w 'Meteor.users', ale ich połączenia są śledzone. –

2

Zamówienie projekt GitHub howmanypeoplearelooking

Meteor testy aplikacji, aby zobaczyć, ilu użytkowników jest teraz online.

+0

To jest żart. Pobrałem kod ('Dumbs = new Meteor.Collection (" dumbs ");' :)) – Matanya

+0

@Matanya: 'Dumbs' jest po prostu dziecinną nazwą kolekcji, ale [aplikacja działa] (https: // github .com/murilopolese/howmanypeoplearelooking/pull/2). –

3

Dzięki napiwkowi Sorhusa udało mi się rozwiązać ten problem. Jego odpowiedź zawiera bicie serca, którego bardzo chciałem uniknąć. Jednak zawierał on sztuczkę używania "bindEnvironment" Meteor'a. Umożliwia to dostęp do kolekcji, która w przeciwnym razie byłaby niedostępna.

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); 
    })); 
    } 
} 
Powiązane problemy