【问题标题】:Sails pubsub how to subscribe to a model instance?Sails pubsub 如何订阅模型实例?
【发布时间】:2015-01-28 14:41:30
【问题描述】:

我正在努力在我的客户端中接收 pubsub 事件。客户端存储 (relux) 使用其 id 从项目中获取数据。据我了解,这会自动为 Sails 套接字订阅实时事件(从 0.10 版开始),但我没有看到它发生。

这是我从 Sails 获取数据的客户商店 (这是 ES6 语法)

onLoadProject(id) {

 var url = '/api/projects/' + id;

 io.socket.get(url, (p, jwres) => {
   console.log('loaded project', id);
   this.project = p;
   this.trigger(p);
 });

 io.socket.on("project", function(event){
   console.log('realtime event', event);
 });
},

然后我在我的项目控制器中创建了一个测试“触摸”动作,只是为了更新 modifiedAt 字段。

touch: function(req, res){
   var id = req.param('id');

   Project.findOne(id)
  .then(function(project) {
    if (!project) throw new Error('No project with id ' + id);

    return Project.update({id: id}, {touched: project.touched+1});
  })
  .then(function(){
    // this should not be required right?
    return Project.publishUpdate(id);
  })
  .done(function() {
    sails.log('touched ok');
    res.ok();

  }, function(e) {
    sails.log("touch failed", e.message, e.stack);
    res.serverError(e.message);
  });
}

这不会在我的客户端代码中触发任何实时事件。我还添加了一个手动 Project.publishUpdate(),但这不应该是必需的吧?

我错过了什么?

-------- 编辑 ----------

我的模型触及属性导致了一个复杂的结果,因为我将它设置为“数字”而不是“整数”,并且在没有 catch() 部分的情况下,承诺错误处理不会捕获 ORM 异常。所以上面的代码有效,万岁!但是每个 Project 实例都会收到实时事件。

所以让我重新表述我的问题:

如何将客户端套接字订阅到实例而不是模型?我可以在客户端检查 id 并检索更新的实例数据,但这似乎效率低下,因为每个客户都会收到有关每个项目的通知,即使他们只应该关心一个项目。

----- 再次编辑 ------

所以没关系。我从每个实例中获取更新的原因仅仅是因为在我的应用程序开始时我触发了 findAll 来获取可用项目的列表。结果,我的套接字被所有这些订阅了。解决方法是通过普通的 http 而不是套接字启动该调用,或者使用单独的控制器操作来检索列表(从而绕过蓝图路由)。我选择了第二个选项,因为在我的情况下,在选择一个之前获取所有项目数据是很愚蠢的。

【问题讨论】:

  • 如果不进行测试,我无法确定您的代码是怎么回事,但您肯定确实需要Project.publishUpdate。如果您使用blueprint methods,Sails 只会自动发送通知。
  • 嗯,为我工作™。你看到loaded project 消息了吗?
  • 感谢@sgress454,代码确实有效。我已经改变了问题。
  • 嗯,不——请求/api/projects/123 只会为您订阅关于项目#123 的消息。您不会收到由Project.publishUpdate(456); 触发的消息。我使用您的代码自己再次验证了这一点。如果无论您“触摸”哪个项目,您都会看到消息,我会检查您的第一个代码块中的 id 是否已实际定义,并且您不会以某种方式获得 all 项目(这会为您订阅有关项目的所有消息,包括您以后创建的消息)。
  • 非常抱歉。我刚刚意识到在加载特定项目以构建所有可用项目的列表之前,我正在执行查找所有请求。嗬!这就是我的客户订阅所有内容的原因。我将为此采取单独的行动以避免这种情况。

标签: sails.js publish-subscribe


【解决方案1】:

所以回答我自己的问题。我从每个实例中获取更新的原因仅仅是因为在我的应用程序开始时我触发了 findAll 来获取可用项目的列表。结果,我的套接字被所有这些订阅了。

解决方法是通过普通的 http 而不是套接字启动该调用,或者使用单独的控制器操作来检索列表(从而绕过蓝图路由)。我选择了第二个选项,因为在我的情况下,在选择一个之前获取所有资源数据是很愚蠢的。

这是我用来列出所有资源的函数,在这里我过滤了与最初浏览列表无关的部分数据。

list: function(req, res) {

Project.find()
  .then(function(projects) {

    var keys = [
      'id',
      'name',
      'createdAt',
      'updatedAt',
      'author',
      'description',
    ];

    return projects.map(function(project){
      return _.pick(project, keys);
    });
  })
  .catch(function (e){
    res.serverError(e.message);
  })
  .done(function(list){
    res.json(list);
  }, function(e) {
    res.serverError(e.message);
  });

},

请注意,当用户加载一个资源(在我的例子中是项目)然后切换到另一个资源时,客户端将订阅这两个资源。我相信它需要一个请求,您可以明确地取消订阅套接字以防止这种情况发生。就我而言,这不是一个问题,但我计划稍后解决。

我希望这对某人有帮助。

【讨论】:

    猜你喜欢
    • 2013-11-18
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多