javascript 您如何在 Meteor 中存储特定于客户端的数据服务器端?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10326347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you store data server side that is specific to a client in Meteor?
提问by joshrtay
Express implements a server side session object that lets you store data specific to a client. How would you do the equivalent in Meteor?
Express 实现了一个服务器端会话对象,可以让您存储特定于客户端的数据。你会如何在 Meteor 中做同样的事情?
strack recommended using a collection. This would work if the ids of objects in the collection were session_ids that were exposed both server and client side on the connection objects.
strack 推荐使用一个集合。如果集合中对象的 id 是 session_ids,并且在连接对象上同时公开服务器和客户端,这将起作用。
It appears the client and server share a session_id via the LivedataConnection on the client:
看起来客户端和服务器通过客户端上的 LivedataConnection 共享一个 session_id:
if (typeof (msg.session) === "string") {
var reconnected = (self.last_session_id === msg.session);
self.last_session_id = msg.session;
}
and the LivedataSession object on the server:
和服务器上的 LivedataSession 对象:
self.id = Meteor.uuid();
But the Meteor API doesn't expose these objects. What is the correct way of accessing the session information?
但是 Meteor API 不会公开这些对象。访问会话信息的正确方法是什么?
It would be really convenient if a client's Session object synced with a server side Session object unique to the client that is accessible from Meteor#publish and Meteor#methods.
如果客户端的 Session 对象与客户端独有的服务器端 Session 对象同步,该对象可从 Meteor#publish 和 Meteor#methods 访问,那将非常方便。
回答by BenjaminRH
The user-session smart packageI wrote for Meteor is designed exactly for this. It provides all the methods of the Meteor Session
API (with the exception of setDefault
), and some additional ones as well. It's reactive, and all the changes are persistent. Best of all, it's available both on the client, and on the server with an additional userId
argument.
我为 Meteor 编写的用户会话智能包正是为此而设计的。它提供了 Meteor Session
API 的所有方法(除了setDefault
),以及一些额外的方法。它是被动的,所有的变化都是持久的。最重要的是,它在客户端和服务器上都可用,并带有附加userId
参数。
回答by Paul
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.
如果您愿意使用 Meteor 的 Auth 分支,这就是我所做的,并添加了一些评论。我不喜欢乔希的回答,因为我不信任客户!他们说谎。
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}.
注意这里 .magicalobject 不是一个错字,它是我们在 self.set 中使用的参数——{magicalobject:magicObject}。
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.
在服务器上,我们有一个客户端无权访问的 MagicalObjects 集合。相反,我们从魔法对象中发布一个对象——我们称之为“magicalObject”。根据我们的设置,每个对象属于一个用户。所以它是 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).
客户端创建一个集合(其名称为“magicalObject”),然后在服务器数据库中的实际数据发生变化时发送数据。这个集合在设计上只有一个对象,但该对象可以有很多参数(例如magicObject.kazoo 或magicObject.isHarryPotter),或者您可以存储许多不同的对象(例如nonMagicItem)。
回答by Josh Petitt
I think a "meteor" way to do this is:
我认为这样做的“流星”方式是:
On server side create and publish a ClientSession collection
在服务器端创建并发布一个 ClientSession 集合
UserSession = new Meteor.Collection("user_sessions");
Meteor.publish('user_sessions', function (user) {
return UserSession.find(user);
});
On client side
在客户端
Session.set('user_id', 42);
UserSession = new Meteor.Collection("user_sessions");
Meteor.subscribe('user_sessions', Session.get('user_id'));
You now have an application-level UserSession object that is specific to that user that you can put/get stuff.
您现在有一个特定于该用户的应用程序级 UserSession 对象,您可以放置/获取内容。
Also, you can manipulate the UserSession collection on the server using Meteor#methods.
此外,您可以使用 Meteor#methods 操作服务器上的 UserSession 集合。
回答by Vinay Vemula
One thing to note is that UserSession doesn't work for a user who has not logged in at the client. I faced this scenario, since I wanted creation of a new user's data object to be modified before saving to MongoDB. The modification was to add an attribute/field obtained from the URL path of current page (using Iron Route client side route). But I was receiving this error,
需要注意的一件事是 UserSession 不适用于尚未登录客户端的用户。我遇到了这种情况,因为我想在保存到 MongoDB 之前修改创建一个新用户的数据对象。修改是添加从当前页面的 URL 路径获取的属性/字段(使用 Iron Route 客户端路由)。但我收到了这个错误,
"You cannot use UserSession methods when there is no user logged in."
“当没有用户登录时,您不能使用 UserSession 方法。”
So if your use case is restricted to sharing data between client and server for a logged in user, UserSession package seems to do the job.
因此,如果您的用例仅限于在客户端和服务器之间为登录用户共享数据,则 UserSession 包似乎可以完成这项工作。
回答by Raul Bollinger
A session behaves a little differently than a collection. If you are truly looking for a session based solution, use the Session.set() method to of course set your values, and retrieve them when needed with Session.get().
会话的行为与集合略有不同。如果您真的在寻找基于会话的解决方案,当然可以使用 Session.set() 方法来设置您的值,并在需要时使用 Session.get() 检索它们。
回答by strack
I think that's what the Session
is for in meteor-- To store information needed on the client side.
我认为这Session
就是流星的用途——存储客户端所需的信息。
If you need to pass something to the server, maybe put it in a Meteor collection?:
如果您需要将某些内容传递给服务器,可以将其放入 Meteor 集合中吗?:
Cookies = new Meteor.collection("cookies")
Otherwise, just use Session.
否则,只需使用Session。