How do you store data server side that is specific to a client in Meteor?

后端 未结 6 807
陌清茗
陌清茗 2021-02-13 02:15

Express implements a server side session object that lets you store data specific to a client. How would you do the equivalent in Meteor?

strack recommended using a coll

6条回答
  •  孤街浪徒
    2021-02-13 03:08

    If you're willing to use the Auth branch of Meteor, this is what I did with some added comments. I wasn't a fan of Josh's answer because I don't trust clients! They lie.

    In this example, we'll say that each user has a single magical object. And we refuse to use any information the user can manipulate client side (i.e. session variables).

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

    Then, when you want to go and grab your magical object:

    var magicObject = MagicalObject.findOne().magicalobject;
    

    Notice here that .magicalobject is NOT a typo, it's the parameter we used in self.set -- {magicalobject: magicalObject}.

    I apologize for the long answer. But to quickly wrap up: what have we done?

    On the server, we have a collection of MagicalObjects which the client doesn't have access to. Instead, we publish a single object from magical objects -- which we call "magicalObject." According to what we set up, each object belongs to one user. So it's a user specific object as requested by the op.

    The client creates a collection (whose name is "magicalObject"), and then gets sent the data when the actual data in the server database changes. This collection only has one object by design, but that object can have many parameters (e.g. magicalObject.kazoo or magicalObject.isHarryPotter) or you can store many different objects (e.g. nonMagicItem).

提交回复
热议问题