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

Socket.io进度条本地正常,Heroku环境下仅部分功能生效

Heroku + Socket.io + Bull.js 进度推送失效问题解决方案

核心原因拆解

  • Heroku dyno实例隔离:Web dyno(处理HTTP请求)和Worker dyno(处理Bull任务)是独立进程,默认Socket.io内存适配器无法跨实例共享客户端连接状态
  • WebSocket连接超时:Heroku会自动断开55秒无活动的WebSocket连接,未配置心跳会导致后续推送失效
  • 房间关联逻辑缺失:仅在提交任务时关联用户房间,未在客户端连接时主动绑定,导致跨实例推送找不到目标连接

修复方案

1. 用Redis实现跨dyno Socket.io连接共享

Heroku多dyno环境下,必须用Redis适配器让所有实例共享Socket.io的房间和连接状态:

  • 安装依赖:
npm install @socket.io/redis-adapter redis
  • 后端配置Redis适配器:
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');

// 用Heroku Redis插件提供的环境变量初始化客户端
const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
});

需在Heroku控制台添加Heroku Redis插件,确保REDIS_URL环境变量自动配置

2. 分离Bull Worker到独立dyno

将Bull任务处理逻辑从Web dyno中剥离,单独运行Worker进程:

  • 项目根目录创建Procfile:
web: node index.js
worker: node worker.js
  • 将Bull的process逻辑迁移到worker.js,同时在worker.js中初始化Socket.io的Redis适配器(和Web dyno共用同一Redis),确保Worker进程能通过Redis向客户端推送事件

3. 配置WebSocket心跳维持连接

避免Heroku因超时断开连接:

  • 后端Socket.io配置:
const io = require('socket.io')(server, {
  pingInterval: 20000, // 每20秒发送一次心跳
  pingTimeout: 60000, // 60秒未收到响应则断开
  transports: ['websocket'] // 强制使用WebSocket,禁用长轮询 fallback
});
  • 前端Socket.io配置:
import { io } from 'socket.io-client';

const socket = io(process.env.NEXT_PUBLIC_API_URL, {
  transports: ['websocket'],
  reconnection: true,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000,
  timeout: 20000
});

4. 完善用户房间绑定逻辑

确保客户端连接时主动加入用户专属房间:

  • 前端连接成功后发送用户ID:
socket.on('connect', () => {
  socket.emit('join-room', user.id); // user为当前登录用户实例
});
  • 后端处理房间加入:
io.on('connection', (socket) => {
  socket.on('join-room', (userId) => {
    socket.join(userId);
  });
});

此后无论Web/Worker dyno,通过io.to(userId).emit都能精准推送事件给该用户的所有在线客户端

5. 排查工具

  • 实时查看Heroku日志:heroku logs --tail,确认Worker dyno运行状态、Redis连接情况
  • 启用Socket.io调试模式:DEBUG=socket.io* node index.js,查看连接建立、心跳、事件推送的详细日志

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:01:56