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

如何在NestJS同模块服务中访问WebSocketGateway的Server实例?

在NestJS同一模块的服务中访问WebSocketGateway的Server实例

问题场景

使用Socket.io的NestJS项目中,同一模块下的PaymentService需要调用PaymentGateway里由@WebSocketServer()修饰的Server实例执行emit操作,但尝试注入WebSocketAdapter失败,报错:

"Nest can't resolve dependencies of the [ServiceName] (?). Please make sure that the argument dependency at index [0] is available in the [Module] context."

相关代码片段:

PaymentGateway

@WebSocketGateway({ cors: true })
export class PaymentGateway {
  constructor(private readonly paymentService: PaymentService) {}

  @WebSocketServer() server: Server

  @SubscribeMessage('pay')
  @UsePipes(new WSValidationPipe())
  create(@MessageBody() createPaymentDto: CreatePaymentDto,
         @ConnectedSocket() client: Socket
  ) {
    return this.paymentService.create(createPaymentDto, client)
  }
}

PaymentService

@Injectable()
export class PaymentService {
  constructor(private botService: BotService) {}

  async create(createPaymentDto: CreatePaymentDto, client: Socket) {
    // ...
  }

  async sendError(error: ILogError, socketId: string) {
    // this.server.emit('error', error.text) <--- 如何实现?
  }
}

解决方案

方法一:直接注入WebSocketGateway到Service

由于PaymentGateway和PaymentService属于同一模块,Gateway本身是可注入的,直接在Service构造函数中注入Gateway即可访问其server属性:

修改PaymentService:

@Injectable()
export class PaymentService {
  constructor(
    private botService: BotService,
    private readonly paymentGateway: PaymentGateway // 注入Gateway实例
  ) {}

  async create(createPaymentDto: CreatePaymentDto, client: Socket) {
    // ...
  }

  async sendError(error: ILogError, socketId: string) {
    // 访问Gateway中的server实例执行emit
    this.paymentGateway.server.emit('error', error.text);
    // 若需给指定socket发送消息,可使用to方法
    // this.paymentGateway.server.to(socketId).emit('error', error.text);
  }
}

注意:确保PaymentGateway已在模块的providers数组中声明(NestJS通常会自动处理,手动配置模块时需确认)。

方法二:将Server实例注册为自定义提供者

若不想直接依赖Gateway,可将Server实例注册为独立的可注入token:

  1. 在模块文件中定义自定义token:
export const SOCKET_IO_SERVER = Symbol('SOCKET_IO_SERVER');
  1. 在PaymentGateway中通过OnModuleInit钩子注册Server实例:
@WebSocketGateway({ cors: true })
export class PaymentGateway implements OnModuleInit {
  constructor(
    private readonly paymentService: PaymentService,
    private readonly moduleRef: ModuleRef // 注入ModuleRef
  ) {}

  @WebSocketServer() server: Server

  onModuleInit() {
    // 将Server实例注册到容器
    this.moduleRef.register(SOCKET_IO_SERVER, this.server);
  }

  // ... 其他方法
}
  1. 在PaymentService中注入该token对应的Server实例:
@Injectable()
export class PaymentService {
  constructor(
    private botService: BotService,
    @Inject(SOCKET_IO_SERVER) private readonly server: Server // 注入Server实例
  ) {}

  async sendError(error: ILogError, socketId: string) {
    this.server.emit('error', error.text);
    // 或指定socket发送
    // this.server.to(socketId).emit('error', error.text);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:05:35