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

使用node-cron调度Socket.io定时事件未按预期工作

问题诊断与修复方案

后端核心问题

1. Socket.io实例调用拼写错误

你在cron调度里写的gameRoutes.getIOSEasy.emit是拼写错误,对应导出的方法是getIOEasy,且需要调用方法(加括号)来获取实例,而非直接访问属性。

2. Cron表达式错误

你需要实现easy party每20秒触发一次,但当前表达式*/180 * * * * *是每180秒(3分钟)执行一次。node-cron的表达式格式为秒 分 时 日 月 周,每20秒的正确表达式是*/20 * * * * *。

修复后的后端cron代码

// cron schedule - easy party 每20秒触发重置事件
cron.schedule("*/20 * * * * *", () => {
  // 先获取Socket.io实例并判断是否存在,避免报错
  const ioEasy = gameRoutes.getIOEasy();
  if (ioEasy) {
    ioEasy.emit("reset", "Reset message from server");
    console.log("触发easy party重置事件"); // 可选:添加日志验证定时任务是否执行
  }
});

前端核心问题

1. Reset事件参数未正确接收

前端代码中socket.on("reset", () => {})未接收服务器传来的message参数,但控制台打印时用到了该变量,会导致未定义报错,需补充参数接收。

2. Timer的闭包陷阱

用let timer在useEffect中保存定时器ID,组件重新渲染时会丢失引用,导致无法正确清除旧定时器。改用useRef保存定时器ID可避免此问题。

修复后的前端代码

import { useEffect, useState, useRef } from 'react';

// ... 其他组件代码

const timerRef = useRef(null); // 用useRef持久化定时器ID

useEffect(() => {
  const socket = io(serverUrl, {
    path: path,
    auth: {
      crazygames_auth: token,
    },
  });

  // 初始化倒计时定时器
  timerRef.current = setInterval(() => {
    setTimeLeft((prevTime) => {
      if (prevTime === 10) {
        socket.emit("sendResponses", buttonResponses);
      }
      return prevTime - 1;
    });
  }, 1000);

  // 正确接收reset事件的消息参数
  socket.on("reset", (message) => {
    console.log("Received reset event:", message);

    // 清除旧定时器
    if (timerRef.current) {
      clearInterval(timerRef.current);
    }

    setTimeLeft(20); 

    // 重新启动倒计时
    timerRef.current = setInterval(() => {
      setTimeLeft((prevTime) => {
        if (prevTime === 10) {
          socket.emit("sendResponses", buttonResponses);
        }
        return prevTime - 1;
      });
    }, 1000);
  });

  socket.on("disconnect", () => {
    console.log("Disconnected from EasyParty");
  });

  return () => {
    socket.disconnect();
    // 组件卸载时清除定时器
    if (timerRef.current) {
      clearInterval(timerRef.current);
    }
  };
}, [cookies, buttonResponses]);

额外验证步骤

  1. 后端控制台添加日志,确认cron定时任务是否正常触发;
  2. 前端浏览器控制台检查是否有未定义变量、连接失败等报错;
  3. 后端connection事件回调中添加日志,验证客户端是否成功连接Socket.io实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:42:49