2012-04-26 12 views
15

Express implementa un oggetto sessione lato server che consente di memorizzare dati specifici per un client. Come faresti l'equivalente in Meteor?Come si memorizza il lato del server di dati specifico per un client in Meteor?

strack consigliato utilizzando una raccolta. Ciò funzionerebbe se gli id ​​degli oggetti nella raccolta fossero session_ids che erano esposti sia lato server che lato client sugli oggetti di connessione.

Sembra la quota client e il server di un session_id tramite il LivedataConnection sul client:

if (typeof (msg.session) === "string") { 
    var reconnected = (self.last_session_id === msg.session); 
    self.last_session_id = msg.session; 
} 

e l'oggetto LivedataSession sul server:

self.id = Meteor.uuid(); 

Ma l'API Meteor non espone questi oggetti. Qual è il modo corretto di accedere alle informazioni sulla sessione?

Sarebbe davvero comodo se l'oggetto Session di un client fosse sincronizzato con un oggetto Session lato server univoco per il client accessibile dai metodi Meteor # publish e Meteor #.

+1

+1 su client e server trasparenti Sincronizzazione sessioni. Ho pensato che funzionasse in questo modo, ed era confuso che non funzionasse – 7zark7

risposta

-1

Penso che sia quello che lo Session è per in meteor-- Per memorizzare le informazioni necessarie sul lato client.

Se è necessario passare qualcosa al server, forse metterlo in una collezione Meteor ?:

Cookies = new Meteor.collection("cookies") 

In caso contrario, basta usare Session.

3

Penso che un modo "Meteor" per fare questo è:

Sul lato server creare e pubblicare una raccolta ClientSession

UserSession = new Meteor.Collection("user_sessions"); 

Meteor.publish('user_sessions', function (user) { 

    return UserSession.find(user);  
}); 

Sul lato client

Session.set('user_id', 42); 

UserSession = new Meteor.Collection("user_sessions"); 
Meteor.subscribe('user_sessions', Session.get('user_id')); 

Ora avete un oggetto UserSession a livello di applicazione specifico per quell'utente che è possibile inserire/ottenere elementi.

Inoltre, è possibile manipolare la raccolta UserSession sul server utilizzando i metodi Meteor #.

+0

Come si tiene traccia di quando un utente si disconnette senza polling? – joshrtay

+0

IDK? Quello che ho mostrato sarebbe un dato client persistente (non molto diverso da qualsiasi altra collezione di Meteor. –

+0

@joshrtay sembra che dovresti fare una sorta di polling per un'indicazione affidabile di quando un utente si disconnette (supponendo che tu voglia chiudere il finestra o naviga verso un'altra pagina) Vedi http://stackoverflow.com/a/10274212/156060 –

6

Se si è disposti ad utilizzare il ramo Auth di Meteor, questo è ciò che ho fatto con alcuni commenti aggiunti. Non ero un fan della risposta di Josh perché non mi fido dei clienti! Loro mentono.

In questo esempio, diremo che ogni utente ha un singolo oggetto magico. E ci rifiutiamo di usare qualsiasi informazione che l'utente possa manipolare lato client (cioè variabili di sessione).

sul server:

//Create our database 
MagicalObjects = new Meteor.Collection("magicalObjects"); 

// Publish the magical object for the client 
Meteor.publish("get-the-magical-object", function() { 

//In the auth branch, server and client have access to this.userId 
//And there is also a collection of users server side 

var uid = this.userId(); 
//I make sure that when I make this connection, I've created a magical object 
//for each user. 

//Let's assume this adds a parameter to magical object for the userId 
//it's linked to (i.e. magObject.uid = ~user id~) 

//we grab our current user from the users database, and pass to our function 
checkUserHasMagicalItem(Meteor.users.findOne({_id: uid})); 

var self = this; 
console.log('Writing publish'); 
console.log('uid: ' + this.userId()); 

var magicalObject = MagicalObjects.findOne({uid: uid}); 

//Now, I want to know if the magical object is changed -- and update accordingly 
//with its changes -- you might not need this part 

//If you don't- then just uncomment these two lines, ignore the rest 
//self.set("magicObject", uid, {magicalobject: magicalObject}); 
//self.flush(); 

//Here, we're going to watch anything that happens to our magical object 
//that's tied to our user 
var handle = MagicalObjects.find({uid: uid}).observe({ 
    added: function(doc, idx) 
    {  
    //get the latest version of our object 
    magicalObject = MagicalObjects.findOne({uid: uid}); 
    console.log('added object'); 
    //now we set this server side 
    self.set("magicObject", uid, {magicalobject: magicalObject}); 
    self.flush(); 
    }, 
    //I'm not concerned about removing, but 
    //we do care if it is changed 
    changed: function(newDoc, idx, oldDoc) 
    { 
    console.log('changed object'); 
    magicalObject = MagicalObjects.findOne({uid: uid}); 
    self.set("magicObject", uid, {magicalobject: magicalObject}); 
    self.flush();   
    }  
//end observe 

}); 

//for when the player disconnects 
self.onStop(function() { 

    console.log('Stopping'); 
    handle.stop(); 

//end onStop 
}); 

//end publish 
}); 

On Cliente:

//this is the name of our collection client side 
MagicalObject = new Meteor.Collection("magicObject"); 

//notice the name is equal to whatever string you use when you call 
//self.set on the server 

//notice, this is the name equal to whatever string you use when you 
//call Meteor.publish on the server 
Meteor.subscribe("get-the-magical-object"); 

Poi, quando si vuole andare e afferrare il vostro oggetto magico:

var magicObject = MagicalObject.findOne().magicalobject; 

Avviso qui che.magicobject NON è un refuso, è il parametro che abbiamo usato in self.set - {magicalobject: magicalObject}.

Mi scuso per la lunga risposta. Ma per concludere rapidamente: cosa abbiamo fatto?

Sul server, abbiamo una collezione di MagicalObjects a cui il cliente non ha accesso. Invece, pubblichiamo un singolo oggetto da oggetti magici - che noi chiamiamo "magicalObject". In base a ciò che impostiamo, ogni oggetto appartiene a un utente. Quindi è un oggetto specifico dell'utente come richiesto dall'op.

Il client crea una raccolta (il cui nome è "magicObject"), quindi riceve i dati quando i dati effettivi nel database del server cambiano. Questa collezione ha un solo oggetto per design, ma quell'oggetto può avere molti parametri (ad esempio magicObject.kazoo o magicalObject.isHarryPotter) oppure è possibile memorizzare molti oggetti diversi (ad esempio nonMagicItem).

0

Una sessione si comporta in modo leggermente diverso rispetto a una raccolta. Se sei veramente alla ricerca di una soluzione basata sulla sessione, usa il metodo Session.set() per impostare i tuoi valori e recuperarli quando necessario con Session.get().

8

Il user-session smart package che ho scritto per Meteor è stato progettato esattamente per questo. Fornisce tutti i metodi dell'API Meteor Session (con l'eccezione di setDefault) e alcuni aggiuntivi. È reattivo e tutti i cambiamenti sono persistenti. Meglio di tutti, è disponibile sia sul client che sul server con un ulteriore argomento userId.

+2

Pacchetto eccellente: questo è quello che la Session di Meteor dovrebbe essere di default.È anche più facile da gestire il problema che ho archiviato con le funzioni di pubblicazione –

+1

Questo è un ottimo pacchetto. Perché hai scelto di affidarti a 'userId'? Non è possibile fare affidamento su un 'sessionId', che funzionerebbe anche senza essere loggato? Non ho ancora visto il tuo codice. Prendo un ristorante e inizio a guardarlo per capire meglio tutto questo –

1

Una cosa da notare è che UserSession non funziona per un utente che non ha effettuato l'accesso al client. Ho affrontato questo scenario, dal momento che volevo la creazione di un nuovo oggetto dati di un utente da modificare prima di salvare su MongoDB. La modifica consisteva nell'aggiungere un attributo/campo ottenuto dal percorso URL della pagina corrente (usando il percorso laterale del client Iron Route). Ma stavo ricevendo questo errore,

"Non è possibile utilizzare i metodi UserSession quando non ci sono utenti loggati."

Quindi se il caso d'uso è limitato alla condivisione di dati tra client e server per un utente connesso, il pacchetto UserSession sembra fare il lavoro.

Problemi correlati