You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sails.js中sails.io.js无法接收model.publish()事件,如何订阅所有CRUD操作记录事件?

解决Sails.js 1.x中无法接收模型实时事件的问题

我刚帮你梳理了下问题,核心原因是Sails.js 1.x在实时事件订阅机制上做了调整,和旧版本的默认行为不一样了。你现在的写法没满足新版本的订阅要求,所以收不到事件,下面一步步给你解决:

问题根源

在Sails.js 1.x之前,调用io.socket.get('/model')可能会自动帮你订阅模型的全局事件,但新版本里这个行为被移除了——你必须显式订阅对应的频道(全局模型频道或单个记录频道),才能收到事件。

另外你手动调用Job.publish([job.id], job)是向「订阅了该特定记录的客户端」发事件,但你的客户端根本没订阅这条新创建的job的ID,自然收不到。

解决方案

方案一:订阅模型全局事件(接收所有Job的CRUD事件)

这个方案适合需要接收所有Job记录创建、更新、删除事件的场景:

1. 服务器端添加订阅接口

在JobController.js里新增一个subscribe方法,用来处理客户端的全局订阅请求:

// JobController.js
subscribe: async function(req, res) {
  // 把当前客户端订阅到Job模型的全局事件频道
  Job.subscribe(req);
  // 如果需要同时订阅所有已存在的Job记录,加上下面这行
  // await Job.subscribe(req, await Job.find());
  return res.ok({ message: "已成功订阅所有Job事件" });
}

2. 客户端修改订阅逻辑

调整客户端代码,先完成socket连接,再订阅全局频道,最后注册事件监听器:

<script>
  // 等待socket连接成功后再操作
  io.socket.on('connect', function() {
    // 先订阅Job模型的全局事件频道
    io.socket.get('/job/subscribe', function(body, JWR) {
      if (JWR.statusCode === 200) {
        console.log('订阅Job全局事件成功');
      }
    });

    // 注册Job事件监听器(放在最外层,不要嵌套在请求回调里)
    io.socket.on('job', function(msg) {
      console.log("收到Job事件:", msg);
      // 你可以根据msg.verb区分事件类型:created/updated/destroyed
      if (msg.verb === 'created') {
        console.log('新Job创建:', msg.data);
      }
    });

    // 延迟启动测试任务
    setTimeout(function() {
      io.socket.get('/job/submittest', function(body, JWR) {
        console.log('测试任务已启动');
      });
    }, 2000);
  });
</script>

方案二:用Sails内置CRUD事件方法(更规范)

Sails提供了publishCreate/publishUpdate/publishDestroy这些内置方法,它们会自动处理事件格式,并且能同时向全局频道和单个记录频道发送事件,比手动调用publish更可靠。

修改你的Job.js模型里的test方法:

// Job.js模型
test: async function(dataset) { 
  let count = 0; 
  setInterval(async function() { 
    count++; 
    let newjob = { dataset: dataset, state: 'delayed', name: "job name "+count }; 
    let job = await Job.create(newjob).fetch();
    sails.log.info('created test job: ', JSON.stringify(job));
    // 用内置的publishCreate发送创建事件
    await Job.publishCreate(job);
  }, 10000); 
}

这样只要客户端通过方案一的subscribe接口订阅了全局频道,就能自动收到这条创建事件。

额外检查点

  1. 确认客户端socket连接正常:可以在io.socket.on('connect')里打印日志,确保连接成功。
  2. 检查服务器端日志:确认publishCreate方法正常执行,没有报错。
  3. 注意事件格式:Sails 1.x的事件对象里会包含verb字段(标识事件类型)和data字段(记录数据),可以打印完整的msg查看结构。

内容的提问来源于stack exchange,提问作者eyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:42:48