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

NestJS中获取指定房间所有连接Socket的最佳方法(无IO实例)

在NestJS中获取指定房间内所有已连接Socket的最佳方式

1. 在WebSocket网关内直接获取

在你的WebSocket网关类中,通过@WebSocketServer()装饰器注入Socket.IO的Server实例,就能直接调用fetchSockets()方法:

import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server } from 'socket.io';

@WebSocketGateway()
export class ChatGateway {
  @WebSocketServer()
  server: Server;

  async getRoomConnectedSockets(roomId: string) {
    // 获取指定房间内的所有Socket实例
    const sockets = await this.server.in(roomId).fetchSockets();
    // 可按需提取Socket的关键信息,比如ID、客户端握手数据
    return sockets.map(socket => ({
      socketId: socket.id,
      userInfo: socket.handshake.auth,
    }));
  }
}

2. 在非网关服务中获取IO实例

如果需要在普通服务、控制器中操作Socket,可以把Server实例注入到全局容器:

步骤1:在网关模块中导出Server实例

import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';

@Module({
  providers: [
    ChatGateway,
    {
      provide: 'SOCKET_IO_SERVER',
      useFactory: (gateway: ChatGateway) => gateway.server,
      inject: [ChatGateway],
    },
  ],
  exports: ['SOCKET_IO_SERVER'],
})
export class ChatModule {}

步骤2:在目标服务中注入使用

import { Injectable, Inject } from '@nestjs/common';
import { Server } from 'socket.io';

@Injectable()
export class RoomService {
  constructor(
    @Inject('SOCKET_IO_SERVER') private readonly ioServer: Server,
  ) {}

  async getSocketsInRoom(roomId: string) {
    const sockets = await this.ioServer.in(roomId).fetchSockets();
    return sockets.map(s => ({
      socketId: s.id,
      userId: s.handshake.headers['user-id'],
    }));
  }
}

关键注意点

  • fetchSockets()是Socket.IO v4.0.0及以上版本的API,确保你的socket.io依赖版本达标
  • 若使用了自定义命名空间,需先指定命名空间再操作:this.server.of('/custom-namespace').in(roomId).fetchSockets()
  • 集群部署场景下,需要配置Redis等适配器,才能跨节点获取所有房间内的Socket实例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:15:43