2012-04-26 2 views
15

Express implementiert ein serverseitiges Sitzungsobjekt, mit dem Sie für einen Client spezifische Daten speichern können. Wie würdest du das Äquivalent in Meteor machen?Wie speichern Sie die Datenserverseite, die für einen Client in Meteor spezifisch ist?

Strack mit einer Sammlung empfohlen. Dies würde funktionieren, wenn die IDs der Objekte in der Auflistung session_ids wären, die auf den Verbindungsobjekten sowohl auf der Server- als auch auf der Client-Seite verfügbar gemacht wurden.

Es scheint, Client und Server teilen sich einen Sitzungs_ID über den LivedataConnection auf dem Client:

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

und dem LivedataSession Objekt auf dem Server:

self.id = Meteor.uuid(); 

Aber der Meteor-API nicht aussetzt diese Objekte. Wie ist der korrekte Zugriff auf die Sitzungsinformationen?

Es wäre wirklich praktisch, wenn das Session-Objekt eines Clients mit einem serverseitigen Session-Objekt synchronisiert wird, das für den Client eindeutig ist und über Meteor # publish und Meteor # -Methoden aufgerufen werden kann.

+1

+1 auf transparenten Client und Server Session-Synchronisierung. Ich nahm an, dass es so funktionierte, und war verwirrt, dass es nicht funktionierte – 7zark7

Antwort

-1

Ich denke, das ist, was die Session in Meteor ist - Um Informationen auf der Client-Seite benötigt zu speichern.

Wenn Sie etwas an den Server übergeben müssen, vielleicht steckt es in einem Meteor Sammlung ?:

Cookies = new Meteor.collection("cookies") 

Ansonsten nur Session verwenden.

3

denke ich, ein "Meteor" Weg, dies zu tun ist:

Auf Server-Seite erstellen und eine ClientSession Sammlung

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

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

    return UserSession.find(user);  
}); 

Auf Client-Seite

Session.set('user_id', 42); 

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

veröffentlichen Sie haben jetzt ein UserSession-Objekt auf Anwendungsebene, das für diesen Benutzer spezifisch ist und dem Sie Elemente hinzufügen/entnehmen können.

Sie können auch die UserSession-Sammlung auf dem Server mit Meteor # -Methoden bearbeiten.

+0

Wie behalten Sie im Auge, wenn ein Benutzer trennt, ohne zu fragen? – joshrtay

+0

IDK? Was ich zeigte, wären persistente Kundendaten (nicht wirklich anders als bei jeder anderen Meteor Collection.) –

+0

@joshrtay scheint so zu sein, als müssten Sie eine Art Polling durchführen, um sicher zu stellen, dass ein Benutzer die Verbindung trennt Fenster oder navigiert zu einer anderen Seite. Siehe http://StackOverflow.com/a/10274212/156060 –

6

Wenn Sie bereit sind, den Auth-Zweig von Meteor zu verwenden, habe ich das mit einigen zusätzlichen Kommentaren getan. Ich war kein Fan von Joshs Antwort, weil ich Kunden nicht traue! Sie lügen.

In diesem Beispiel sagen wir, dass jeder Benutzer ein einzelnes magisches Objekt hat. Und wir weigern uns, irgendwelche Informationen zu verwenden, die der Benutzer clientseitig manipulieren kann (d. H. Sitzungsvariablen).

Auf 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 Client:

//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"); 

Dann, wenn Sie gehen wollen und kaufen Sie Ihr magisches Objekt:

var magicObject = MagicalObject.findOne().magicalobject; 

Hinweis hier, dass.magicobject ist kein Tippfehler, es ist der Parameter, den wir in self.set - {magicobject: magicalObject} verwendet haben.

Ich entschuldige mich für die lange Antwort. Aber um schnell abzuschließen: Was haben wir getan?

Auf dem Server haben wir eine Sammlung von MagicalObjects, auf die der Client keinen Zugriff hat. Stattdessen veröffentlichen wir ein einzelnes Objekt aus magischen Objekten - das wir "magicalObject" nennen. Je nach dem, was wir einrichten, gehört jedes Objekt einem Benutzer. Es ist also ein benutzerspezifisches Objekt, wie es von der OP angefordert wird.

Der Client erstellt eine Auflistung (mit dem Namen "magicalObject") und sendet dann die Daten, wenn sich die tatsächlichen Daten in der Serverdatenbank ändern. Diese Sammlung hat nur ein Objekt pro Design, aber dieses Objekt kann viele Parameter haben (z. B. magicalObject.kazoo oder magicalObject.isHarryPotter) oder Sie können viele verschiedene Objekte speichern (z. B. nonMagicItem).

0

Eine Sitzung verhält sich ein wenig anders als eine Sammlung. Wenn Sie wirklich nach einer sitzungsbasierten Lösung suchen, verwenden Sie die Methode Session.set(), um Ihre Werte natürlich festzulegen und sie bei Bedarf mit Session.get() abzurufen.

8

Die user-session smart package Ich schrieb für Meteor ist genau dafür konzipiert. Es bietet alle Methoden der Meteor Session API (mit Ausnahme von setDefault) und einige zusätzliche. Es ist reaktiv und alle Änderungen sind persistent. Das Beste von allem ist, dass es sowohl auf dem Client als auch auf dem Server mit einem zusätzlichen userId Argument verfügbar ist.

+2

Excellent Paket. Das ist, was Meteor Session standardmäßig sein sollte. Wäre auch einfacher, das Problem zu behandeln, das ich eingereicht habe, um Funktionen zu veröffentlichen. –

+1

That is ein tolles Paket. Warum haben Sie sich für "userId" entschieden? Kann man sich nicht einfach auf eine 'sessionId' verlassen, die auch ohne eingeloggt ist? Ich habe deinen Code noch nicht angesehen. Ich schnappe mir ein Diner und schaue hinein, um alles besser zu verstehen –

1

Eine Sache zu beachten ist, dass UserSession nicht für einen Benutzer funktioniert, der nicht am Client angemeldet ist. Ich war mit diesem Szenario konfrontiert, da ich die Erstellung eines neuen Benutzerdatenobjekts vor dem Speichern in MongoDB ändern wollte. Die Änderung bestand darin, ein Attribut/Feld hinzuzufügen, das aus dem URL-Pfad der aktuellen Seite erhalten wurde (unter Verwendung der Route der clientseitigen Iron Route-Route). Aber ich habe diesen Fehler erhalten,

"Sie können UserSession-Methoden nicht verwenden, wenn kein Benutzer angemeldet ist."

Wenn Ihr Anwendungsfall auf die gemeinsame Nutzung von Daten zwischen Client und Server für einen angemeldeten Benutzer beschränkt ist, scheint das UserSession-Paket die Aufgabe zu erfüllen.

Verwandte Themen