簡體   English   中英

如何在Meteor中存儲特定於客戶端的數據服務器端?

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

Express實現了一個服務器端會話對象,允許您存儲特定於客戶端的數據。 你如何在Meteor中做同等效果的?

strack推薦使用一個集合。 如果集合中的對象的id是在連接對象上公開服務器端和客戶端的session_id,則這將起作用。

客戶端和服務器似乎通過客戶端上的LivedataConnection共享session_id:

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

和服務器上的LivedataSession對象:

self.id = Meteor.uuid();

但Meteor API不會公開這些對象。 訪問會話信息的正確方法是什么?

如果客戶端的Session對象與可從Meteor#publish和Meteor#方法訪問的客戶端唯一的服務器端Session對象同步,那將非常方便。

我為Meteor編寫的用戶會話智能包正是為此而設計的。 它提供了Meteor Session API的所有方法( setDefault除外)以及一些其他方法。 它是被動的,所有的變化都是持久的。 最重要的是,它既可以在客戶端上使用,也可以在服務器上使用另外的userId參數。

如果你願意使用Meteor的Auth分支,這就是我做的一些補充評論。 我不是Josh答案的粉絲,因為我不相信客戶! 他們說謊。

在這個例子中,我們會說每個用戶都有一個神奇的對象。 我們拒絕使用用戶可以操縱客戶端的任何信息(即會話變量)。

在服務器上:

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

在客戶端:

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

然后,當你想去抓住你的魔法物品時:

var magicObject = MagicalObject.findOne().magicalobject;

請注意.magicalobject不是拼寫錯誤,它是我們在self.set中使用的參數 - {magicalobject:magicalObject}。

我為這個長期答案道歉。 但要快速結束:我們做了什么?

在服務器上,我們有一組客戶端無權訪問的MagicalObjects。 相反,我們從魔法對象發布一個對象 - 我們稱之為“魔法對象”。 根據我們設置的內容,每個對象屬於一個用戶。 所以它是op所要求的用戶特定對象。

客戶端創建一個集合(其名稱為“magicalObject”),然后在服務器數據庫中的實際數據發生更改時發送數據。 此集合只有一個設計對象,但該對象可以有許多參數(例如magicalObject.kazoo或magicalObject.isHarryPotter),或者您可以存儲許多不同的對象(例如nonMagicItem)。

我認為這樣做的“流星”方式是:

在服務器端創建並發布ClientSession集合

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

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

    return UserSession.find(user);    
});

在客戶端

Session.set('user_id', 42);

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

您現在擁有一個特定於該用戶的應用程序級UserSession對象,您可以放置​​/獲取內容。

此外,您可以使用Meteor#方法在服務器上操作UserSession集合。

需要注意的一點是,UserSession不適用於未在客戶端登錄的用戶。 我遇到了這種情況,因為我想在保存到MongoDB之前創建一個新用戶的數據對象進行修改。 修改是添加從當前頁面的URL路徑獲取的屬性/字段(使用Iron Route客戶端路由)。 但是我收到了這個錯誤,

“當沒有用戶登錄時,您無法使用UserSession方法。”

因此,如果您的用例僅限於在登錄用戶的客戶端和服務器之間共享數據,則UserSession包似乎可以完成這項工作。

會話與集合的行為略有不同。 如果您真的在尋找基於會話的解決方案,請使用Session.set()方法來設置您的值,並在需要時使用Session.get()檢索它們。

我認為這就是Session在流星中的用途 - 存儲客戶端所需的信息。

如果您需要將某些內容傳遞給服務器,可以將其放入Meteor集合中?:

Cookies = new Meteor.collection("cookies")

否則,只需使用Session

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM