2012-04-21 11 views

Odpowiedz

18

Jedną z technik jest wdrożenie "utrzymywanej" metody, którą regularnie wywołuje każdy klient. Zakłada się, że masz user_id przechowywany w każdym klienta Session.

// server code: heartbeat method 
Meteor.methods({ 
    keepalive: function (user_id) { 
    if (!Connections.findOne(user_id)) 
     Connections.insert({user_id: user_id}); 

    Connections.update(user_id, {$set: {last_seen: (new Date()).getTime()}}); 
    } 
}); 

// server code: clean up dead clients after 60 seconds 
Meteor.setInterval(function() { 
    var now = (new Date()).getTime(); 
    Connections.find({last_seen: {$lt: (now - 60 * 1000)}}).forEach(function (user) { 
    // do something here for each idle user 
    }); 
}); 

// client code: ping heartbeat every 5 seconds 
Meteor.setInterval(function() { 
    Meteor.call('keepalive', Session.get('user_id')); 
}, 5000); 
+0

Po wielu poszukiwaniach uważam, że jest to najlepsze rozwiązanie na razie. Dzięki!! – greggreg

+6

Jest to prawie pseudokod, ponieważ nie jest funkcjonalne, tak jak jest: pierwsza setInterval nie ma podanego przedziału. Również komenda Connections.update nie określa aktualizacji {'identyfikator_użytkownika': identyfikator_użytkownika}. Mogą występować inne błędy. To dobry początek. –

+3

@debergalis Czy to nadal jest zalecany sposób sprawdzenia, czy klienci są martwi? – user2602152

1

jeśli używasz uwierzytelniania masz dostęp do ID użytkownika w metodzie i Publish funkcje, można wdrożyć śledzenie tam .. np można ustawić „ostatni widział”, kiedy użytkownik przełącza pokój:

Meteor.publish("messages", function(roomId) { 
    // assuming ActiveConnections is where you're tracking user connection activity 
    ActiveConnections.update({ userId: this.userId() }, { 
     $set:{ lastSeen: new Date().getTime() } 
    }); 
    return Messages.find({ roomId: roomId}); 
}); 
13

myślę Lepszym sposobem jest zamknięcie gniazda złapać zdarzenie w funkcji publikowania.

Meteor.publish("your_collection", function() { 
    this.session.socket.on("close", function() { /*do your thing*/}); 
} 

UPDATE:

Nowsza wersja meteoru wykorzystuje _SESSION tak:

this._session.socket.on("close", function() { /*do your thing*/}); 
+0

To świetnie. Ale wtedy najwyraźniej natknąłem się na ten problem: http://stackoverflow.com/questions/10192938/meteor-code-must-always-run-within-a-fiber-when-calling-collection-insert-on-s – huyz

+0

Dzięki . Oto odpowiedź na moje pytanie: [Meteor obserwuj bieganie na zawsze] (http://stackoverflow.com/q/12902392/599991) – zVictor

+3

Używam meteor 0.6.1 i dla tej linii 'this.session.socket.on (" close ", function() {/ * wykonaj twoją rzecz * /});' mój serwer zwraca _TypeError: Nie można odczytać właściwości 'socket' z undefined_ Ale kiedy poprawię to do 'this.session.socket.on (" close ", function() {/ * do rzeczy * /}); 'działa świetnie, dzięki – fantom

2

I zostały wdrożone smart pakiet Meteor, który śledzi wszystkie podłączone sesje z różnych sesji i wykrywa zarówno wylogowania sesji i rozłączaj zdarzenia, bez kosztownego keepalive.

https://github.com/mizzao/meteor-user-status

celu wykrycia zdarzenia rozłączanie/wylogowania, można po prostu wykonaj następujące czynności:

UserStatus.on "connectionLogout", (info) -> 
    console.log(info.userId + " with session " + info.connectionId + " logged out") 

Można również użyć go reaktywnie. Sprawdź to!

EDIT:v0.3.0 z obsługą stanu teraz śledzi użytkowników bezczynności, jak dobrze!

+0

Czy można to zrobić na podstawie strony, a nie całej aplikacji? – Scalahansolo

+0

Tak, chociaż nie zostało to jeszcze zaimplementowane. Otwórz żądanie funkcji! –

-1

Używam Iron Router i wywołuję mój kod oczyszczania na unload zdarzeń mojego głównego kontrolera. Na pewno nie będzie to miało wpływu na zamykanie karty, ale nadal jest wystarczająco dobre dla wielu przypadków użycia.

ApplicationController = RouteController.extend({ 
    layoutTemplate: 'root', 
    data: {}, 
    fastRender: true, 
    onBeforeAction: function() { 
     this.next(); 
    }, 
    unload: function() { 
     if(Meteor.userId()) 
      Meteor.call('CleanUpTheUsersTrash'); 
    }, 
    action: function() { 
     console.log('this should be overridden by our actual controllers!'); 
    } 
}); 
Powiązane problemy