Как вы храните серверную часть данных, специфичную для клиента в Meteor?
Express реализует объект сеанса на стороне сервера, который позволяет хранить данные, специфичные для клиента. Как бы вы сделали эквивалент в Метеор?
strack рекомендуется использовать коллекцию. Это будет работать, если идентификаторы объектов в коллекции были session_id, которые были открыты как на стороне сервера, так и на стороне клиента на объектах соединения.
Кажется, клиент и сервер совместно используют session_id через LivedataConnection на клиенте:
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 не раскрывает эти объекты. Каков правильный способ доступа к информации о сеансе?
Было бы очень удобно, если бы объект сеанса клиента синхронизировался с объектом сеанса на стороне сервера, уникальным для клиента, доступным из методов Meteor # publish и Meteor #.
Ответы
Ответ 1
пользовательский сеанс интеллектуального пакета, который я написал для Meteor, предназначен именно для этого. Он предоставляет все методы API Meteor Session
(за исключением setDefault
) и некоторые дополнительные. Он реактивен, и все изменения настойчивы. Лучше всего, он доступен как на клиенте, так и на сервере с дополнительным аргументом userId
.
Ответ 2
Если вы хотите использовать ветвь Auth Meteor, это то, что я сделал с некоторыми добавленными комментариями. Я не был поклонником Джоша, потому что я не доверяю клиентам! Они лгут.
В этом примере мы скажем, что каждый пользователь имеет один магический объект. И мы отказываемся использовать любую информацию, которую пользователь может манипулировать клиентской стороной (то есть переменные сеанса).
На сервере:
//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 assume this adds a parameter to magical object for the userId
//it 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 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". В соответствии с тем, что мы создали, каждый объект принадлежит одному пользователю. Таким образом, это пользовательский объект, запрошенный оператором.
Клиент создает коллекцию (чье имя является "magicalObject" ), а затем отправляет данные при изменении фактических данных в базе данных сервера. У этой коллекции только один объект по дизайну, но этот объект может иметь много параметров (например, magicalObject.kazoo или magicalObject.isHarryPotter), или вы можете хранить много разных объектов (например, nonMagicItem).
Ответ 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 на уровне приложения, специфичный для этого пользователя, который вы можете положить/получить материал.
Кроме того, вы можете манипулировать коллекцией UserSession на сервере с использованием методов Meteor #.
Ответ 4
Следует отметить, что UserSession не работает для пользователя, который не вошел в систему на клиенте. Я столкнулся с этим сценарием, так как хотел создать новый пользовательский объект данных, который будет изменен до сохранения в MongoDB. Модификация заключалась в том, чтобы добавить атрибут/поле, полученное из URL-адреса текущей страницы (с использованием маршрута на стороне клиента Iron Route). Но я получал эту ошибку,
"Вы не можете использовать методы UserSession, когда пользователь не зарегистрирован."
Итак, если ваш прецедент ограничен для обмена данными между клиентом и сервером для зарегистрированного пользователя, пакет UserSession, похоже, выполняет эту работу.
Ответ 5
Сеанс ведет себя несколько иначе, чем сбор. Если вы действительно ищете решение на основе сеанса, используйте метод Session.set(), чтобы, конечно, установить свои значения и получить их при необходимости с Session.get().
Ответ 6
Я думаю, что для <метеорологии Session
- для хранения информации, необходимой на стороне клиента.
Если вам нужно передать что-то на сервер, возможно, поместите его в коллекцию Meteor?:
Cookies = new Meteor.collection("cookies")
В противном случае просто используйте Session.