【发布时间】: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