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

NestJS中Socket.io Redis Adapter无法触发Gateway事件的问题

解决NestJS Socket.io Redis Adapter触发@SubscribeMessage事件的问题

核心原因

直接向Redis发布原始字符串(比如'test')不符合Socket.io Redis Adapter要求的消息结构。Socket.io的Redis适配器会将消息封装为包含type、nsp、data等字段的特定JSON格式,只有符合该格式的消息,才能被Gateway的@SubscribeMessage正确识别并触发对应方法。

具体解决方案

1. 按Socket.io规范构造Redis消息

在另一个NestJS应用中,不要直接发布原始字符串,而是构造符合Socket.io要求的JSON结构后再发布:

// 另一个NestJS应用的Redis发布代码示例
await redisClient.publish(
  'socket.io#/#', // 频道格式规则:socket.io#<命名空间>#,默认命名空间为/,所以是socket.io#/#
  JSON.stringify({
    type: 'event', // 固定值为event
    nsp: '/', // 与Gateway使用的命名空间保持一致,默认是/
    data: ['test', '你的消息内容'], // 第一个元素是事件名,后续元素为事件参数
    id: '1', // 可选字段,消息ID,可省略
  })
);

2. 匹配Gateway的命名空间配置

如果你的EventsGateway设置了自定义命名空间,比如:

@WebSocketGateway({ namespace: '/chat' })
export class EventsGateway {
  @SubscribeMessage('test')
  handleTest(client: Socket, payload: any) {
    // 业务处理逻辑
  }
}

那么Redis发布的频道需要改为socket.io#/chat#,同时消息中的nsp字段也要设为/chat。

3. 确保Redis Adapter初始化正确

检查RedisIoAdapter和main.ts的配置,保证Redis连接与适配器挂载逻辑正确:

// RedisIoAdapter示例代码
export class RedisIoAdapter extends IoAdapter {
  private redisAdapter: any;

  async connectToRedis() {
    const pubClient = createClient({ url: 'redis://localhost:6379' });
    const subClient = pubClient.duplicate();
    await Promise.all([pubClient.connect(), subClient.connect()]);
    this.redisAdapter = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions) {
    const server = super.createIOServer(port, options);
    server.adapter(this.redisAdapter);
    return server;
  }
}

// main.ts中的初始化逻辑
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const redisIoAdapter = new RedisIoAdapter(app);
  await redisIoAdapter.connectToRedis();
  app.useWebSocketAdapter(redisIoAdapter);
  await app.listen(3000);
}
bootstrap();

4. 移除手动订阅Redis频道的逻辑

不要在connectToRedis方法中手动订阅Redis频道,Socket.io的Redis适配器会自动处理频道订阅与消息转发,手动订阅会干扰适配器的正常工作流程。

测试验证

  1. 启动两个NestJS应用,确保Redis服务正常运行。
  2. 在另一个应用中按照正确格式发布消息。
  3. 检查EventsGateway中@SubscribeMessage('test')修饰的方法是否被触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:46:19