Javascript 如何在Meteor中存储特定于客户端的数据服务器端?

Javascript 如何在Meteor中存储特定于客户端的数据服务器端?,javascript,session,meteor,Javascript,Session,Meteor,Express实现一个服务器端会话对象,用于存储特定于客户端的数据。你会如何在《流星》中做到这一点 strack建议使用集合。如果集合中对象的ID是会话\u ID,并且在连接对象上同时公开了服务器端和客户端,那么这将起作用 客户端和服务器似乎通过客户端上的LivedataConnection共享会话id: if (typeof (msg.session) === "string") { var reconnected = (self.last_session_id === msg.sessi

Express实现一个服务器端会话对象,用于存储特定于客户端的数据。你会如何在《流星》中做到这一点

strack建议使用集合。如果集合中对象的ID是会话\u ID,并且在连接对象上同时公开了服务器端和客户端,那么这将起作用

客户端和服务器似乎通过客户端上的LivedataConnection共享会话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();
但是MeteorAPI没有暴露这些物体。访问会话信息的正确方式是什么


如果客户端的会话对象与客户端独有的服务器端会话对象同步,并且可以通过Meteor#publish和Meteor#方法访问,这将非常方便。

我认为这就是Meteor中的
会话
的目的——存储客户端所需的信息

如果您需要将某些内容传递给服务器,可以将其放入Meteor collection中:

Cookies = new Meteor.collection("cookies")
否则,只需使用。

我认为“流星”方法是:

在服务器端创建并发布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集合。

如果您愿意使用Meteor的Auth分支,这就是我添加的一些注释所做的。我不喜欢乔希的回答,因为我不信任客户!他们撒谎

在本例中,我们将说每个用户都有一个魔法对象。我们拒绝使用用户可以操纵客户端的任何信息(即会话变量)

在服务器上:

//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集合,客户端无权访问这些对象。取而代之的是,我们从魔法对象中发布一个对象——我们称之为“magicalObject”。根据我们的设置,每个对象都属于一个用户。因此,它是op请求的特定于用户的对象


客户端创建一个集合(其名称为“magicalObject”),然后在服务器数据库中的实际数据发生更改时接收数据。此集合在设计上只有一个对象,但该对象可以有多个参数(例如magicalObject.kazoo或magicalObject.isHarryPotter),也可以存储多个不同的对象(例如nonMagicItem)

会话的行为与集合稍有不同。如果您确实在寻找基于会话的解决方案,那么使用session.set()方法当然可以设置您的值,并在需要时使用session.get()检索它们。

我为Meteor编写的工具正是为此而设计的。它提供Meteor
会话的所有方法
API(除了
setDefault
),以及一些附加方法。它是被动的,所有的变化都是持久的。最重要的是,它在客户端和服务器上都可用,并带有一个附加的
userId
参数。

需要注意的是,UserSession不适用于未登录客户端的用户。我面临这种情况,因为我希望在保存到MongoDB之前修改新用户数据对象的创建。修改是添加从当前页面的URL路径获得的属性/字段(使用Iron Route客户端路由)。但是我收到了这个错误

“当没有用户登录时,您不能使用UserSession方法。”


因此,如果您的用例仅限于为登录用户在客户端和服务器之间共享数据,那么UserSession软件包似乎可以完成这项工作。

如何跟踪用户在未轮询的情况下断开连接?IDK?我展示的将是一个持久的客户端数据(与任何其他Meteor收集没有任何区别。@joshrtay似乎必须进行某种轮询,以可靠地指示用户何时断开连接(假设您的意思是关闭窗口或导航到另一个页面)。请参阅使用
user\u id
,因为这不是很好。用户可以将
user\u id
会话变量设置为另一个数字,以从集合中获得另一个结果。
Meteor.publish
有一个!而且session.set并不像我们预期的那样是持久的。用户刷新其浏览器,我们将不知道他们是谁e、 在透明的客户端和服务器会话同步上+1。我假设它是这样工作的,但我觉得它不是一个很好的包。这是Meteor的会话在默认情况下应该是这样的。这也会更容易处理我提交的重新发布函数的问题。这是一个很棒的包。但是为什么你选择依赖
userId
呢?是吗仅仅依靠
会话ID
是不可能的,即使不登录也可以工作?我还没有看过你的代码。我找了一些餐车,开始研究它,以便更好地了解所有这些