【问题标题】:Filter notifications within policy在策略中过滤通知
【发布时间】:2015-11-18 02:46:48
【问题描述】:

每当创建(或删除/修改)模型时,每个连接的套接字都会通过 Sails 自动监视设置得到通知。这在某种程度上很好,但我想在某个时候过滤这些通知。

我的应用程序有自己的“通知”,应该发送给各自的接收者。所以他们的解剖结构有点像:id, message, receiver, sender

身份验证是本地护照实现。

侦听notification 事件会导致每次创建通知时都会收到通知。

// client: app.js
io.socket.on('notification', function(evt) { console.log(evt); });

我现在尝试实现的是过滤这些通知以匹配用户 ID。我编写了一个适用于/notification 事件的策略。

// Policy: forUser
module.exports = function(req, res, next) {
  // ... whatever ... //

  return next();
}

在政策范围内

  'notification': {
    'create': ['passport', 'forUser']
  }

我现在的问题是:如何实施这个政策?我想只检查notification.receiver == req.user.id,但是如何在策略中获取通知模型(如果这是正确的方法)?

谢谢。

编辑:尝试实施房间解决方案,但我没有在客户端收到任何通知。

我在 NotificationController 中更改了订阅功能:

subscribe: function(req, res) {
        sails.log.info('Your user id: ' + req.user.id);
        sails.sockets.join(req.socket, 'user_notifications_' + req.user.id);
        res.json({
            room: 'user_notifications_' + req.user.id
        });
    },

并为我的模型添加了afterCreate 方法:

afterCreate: function(model, next) {
    sails.sockets.broadcast('user_notifications_' + model.receiver, { test: 'hello' });
    next();
  }

客户端上的代码现在是:

  io.socket.get("/notification/subscribe", function(data, jwr) {
    io.socket.on(data.room, function(obj) {
      console.log(obj);
    });
  });

调用订阅方法并返回正确的房间名称。但是我在拨打/notification/create?message=test&receiver=1 时没有收到任何消息。调用了afterCreate 方法,所有用户id 都是正确的(因为只有一个用户),但是什么也没有发生。

编辑2: 好像加入房间失败了。

sails.sockets.join(req.socket, 'testroom');
// For testing
sails.log.debug(sails.sockets.socketRooms(req.socket));

房间已创建,但套接字未订阅。

编辑3: 找到了解决方案。界面完成后我会第一时间发布 GitHub 链接。

【问题讨论】:

  • 您希望此策略过滤传出的 websocket 消息吗?这些策略不适用于事件,而是适用于控制器。当 socket.io 向客户端发送消息时,他们无法控制会发生什么。我在你的问题中遗漏了什么吗?
  • 不,没错。我想过滤传出的套接字消息。如果策略无法做到这一点,那么过滤套接字消息的正确方法是什么?

标签: javascript node.js sockets sails.js


【解决方案1】:

您是否使用sails.sockets.blast() 发送通知?

要发送自定义事件,您可以使用sails.sockets.emit()

// Controller action
actionSendingNotification: function(req, res) {
  // Retrieve the user socket ID and the data to send
  // ...
  sails.sockets.emit(userSocketId, 'notification', data);
}

您必须能够知道用户是否有活动的 websocket 连接并检索他的套接字 ID。他可以在他的浏览器中打开几个选项卡和几个 websocket 连接......

可能更好的解决方案是使用sails.sockets.join()sails.sockets.broadcast()。然后,您将在socket.io 中创建已连接用户观察到的事件 之间的关联。

// When the user creates a websocket connection, subscribe him to the model room
// This action MUST be called by a websocket request
// Here I assume your event is related to a model
subscribeToModelRoom: function(req, res) {
  var roomName = 'myModelRoom' + req.param('model_id');
  sails.sockets.join(req.socket, roomName);
  res.json({
    message: 'Subscribed to a room called '+roomName+'!'
  });
}

那么你每次向房间发送消息,订阅的用户都会收到。

// When the model has to send a notification, use broadcast() to send it to the room associated to the model.
sails.sockets.broadcast('myModelRoom' + modelInstance.id, 'notification', data);

编辑 再次阅读您的问题,我将添加一些解释。

您似乎试图根据用户的user.id 向他发送通知。当您发送此通知时,您不能假设此用户将通过 websocket 连接。 您不会向用户发送事件,而是向打开的 websocket 连接发送事件(可能已通过身份验证)。

如果用户不能错过通知,则必须将其存储在数据库中。然后,您将在用户连接时将其显示给用户。

如果您希望用户在连接时得到实时通知,您可以在初始化他经过身份验证的 websocket 连接时为他订阅一个房间"user_notifications_" + user.id。然后在您创建新通知时向该房间发出事件。

您可以添加逻辑来管理看到/未看到通知并删除过时的记录。

这样,您可以将信息实时发送给您的用户,并且如果没有人来接收信息,您也不会丢失信息。

【讨论】:

  • 非常感谢您的详细解释。修改了我的应用程序并玩弄了房间,但我仍然没有收到任何通知。我已经编辑了条目并添加了我的更改。
  • 很高兴你能成功!如果对您有帮助,您能接受答案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多