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#methods访问的客户端唯一的服务器端Session对象同步,那将非常方便。
答案 0 :(得分:8)
我为Meteor写的user-session smart package正是为此而设计的。它提供了Meteor Session
API的所有方法(setDefault
除外),还有一些其他方法。它是被动的,所有的变化都是持久的。最重要的是,它既可以在客户端上使用,也可以在服务器上使用额外的userId
参数。
答案 1 :(得分:7)
如果您愿意使用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)。
答案 2 :(得分:3)
我认为这样做的一种“流星”方式是:
在服务器端创建和发布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集合。
答案 3 :(得分:1)
需要注意的一点是,UserSession对于尚未登录客户端的用户不起作用。我遇到了这种情况,因为我想在保存到MongoDB之前创建一个新用户的数据对象。修改是添加从当前页面的URL路径获取的属性/字段(使用Iron Route客户端路由)。但是我收到了这个错误,
"当没有用户登录时,您无法使用UserSession方法。"
因此,如果您的用例仅限于在登录用户的客户端和服务器之间共享数据,那么UserSession包似乎可以完成这项工作。
答案 4 :(得分:0)
会话与集合的行为略有不同。如果您真的在寻找基于会话的解决方案,请使用Session.set()方法来设置您的值,并在需要时使用Session.get()来检索它们。
答案 5 :(得分:-1)
我认为这就是流星中Session
的含义 - 存储客户端所需的信息。
如果您需要将某些内容传递给服务器,可以将其放入Meteor集合中?:
Cookies = new Meteor.collection("cookies")
否则,只需使用Session。