Несколько отдельных чатов в sails.js
Я видел несколько примеров функциональности чата на sails.js. Тем не менее, все они создают один большой чат, где размещаются все пользователи.
Как создать несколько чатов (чтобы сообщения, размещенные в одном чате, не отображались в другом).
Я не уверен, что правильно понимаю проблему. Похоже, что происходит, что клиент делает io.socket.post('/message', { someMessageData })
и, как результат, подписаться на все сообщения.
Есть ли способ отфильтровать его (на стороне сервера), чтобы он подписывался на сообщения только в одной комнате чата.
Я видел, что у сокетов были идентификаторы. И если бы серверная сторона использовала напрямую socket.io, я бы просто собрал список идентификаторов, на которые нужно отправлять сообщения.
Однако Sails.js скрывает этот уровень. И как результат, я не уверен, как настроить это на сервере.
Я видел похожий вопрос. Однако он достаточно старый (учитывая скорость изменений в Sails.js). Я не уверен, куда мне поместить код относительно Model.subscribe и Model.publish, принимая во внимание, что все это скрыто по соглашению (так что мне кажется, что мне нужно переопределить поведение по умолчанию при автоматической подписке).
2 ответа
Прежде всего, я считаю, что есть три документа:
- http://sailsjs.org/
- Некоторая документация под github, которая не отображается на главном сайте. Как пример github.com/balderdashy/sails-docs/blob/0.9/sockets.md
- Некоторая новая документация https://github.com/balderdashy/sails-docs/blob/0.9/reference/ModelProperties.md
Честно говоря, это было сложно собрать только из документации. Итак, я посмотрел в исходном коде.
Тем не мение. Проблема была в том, что у моей модели есть связь с коллекцией. И как только мой клиент прочитал объект моей модели, он стал подписываться на модель этой коллекции. И я видел ВСЕ изменения для этой модели коллекции.
Я обнаружил, что есть конфигурация проекта под названием "Autowatch". Он управляет этим поведением (стоит ли подписываться на модель всех ассоциаций). Это работает как шарм, если вы выключите его в config/blueprints.js.
Сначала вам нужно переопределить find
а также create
чертежи в соответствии с этим.
Второе, присмотритесь к объявлению find
план. Чтобы достичь своей цели, вам нужно обновить критерии запроса и присоединиться к соответствующей (средней фильтрации) комнате.
Пример обновления критериев:
// Look up the model
var Model = actionUtil.parseModel(req),
criteria = actionUtil.parseCriteria(req),
user = req.user && req.user.id || 0,
allowed = user ? [0, user] : [0],
watchFilters = req.options.hasOwnProperty('watchFilters') ? req.options.watchFilters(req) : false,
classRoom = "sails_model_create_" + Model.identity;
// i need filter by authenticated user so forbidden all other requests
if (allowed.indexOf(user) === -1) {
return res.forbidden();
}
if (watchFilters) {
classRoom = _.reduce(Object.keys(watchFilters), function (classRoom, field) {
return classRoom + "_" + field + "_" + watchFilters[field];
}, classRoom);
}
if (_.result(Model, 'ownerFiltered')) {
criteria.user = user
}
Есть один звонок watch
метод немного дальше,
if (req.options.autoWatch) { Model.watch(req); }
вам нужно заменить его на это:
if (req.options.autoWatch) {
sails.sockets.join(socket, classRoom);
sails.log.silly("Subscribed socket ", sails.sockets.id(req.socket), "to", classRoom, "filtered by", watchFilters);
}
для того, чтобы присоединиться к соответствующей комнате.
В-третьих, заменить вызов publishCreate
в create
план с собственным broadcast
вызов:
Model.broadcast(classRoom, Model.identity, {
verb: 'created',
data: data,
id: data[Model.primaryKey]
}, req.socket);
Теперь вы можете фильтровать ваши модели с помощью чего-то вроде этого:
watchFilters: function (req) {
return {
user: req.user.id,
assembly: req.user.assembly || 1
};
},