如何在NestJS控制器中注入BeeQueue任务并完成模块注册
实现方案
1. 改造Job类为Nest可注入提供者
给ClickToCallJob添加@Injectable()装饰器使其支持Nest依赖注入,同时修正原有逻辑中重复注册队列处理器和事件监听的问题,将只需要执行一次的初始化逻辑放到构造函数中:
import { Injectable } from '@nestjs/common'; import { IBeeQueueJob } from './bee-queue-job.interface'; import { FreeswitchCallSystemService } from './freeswitch-call-system.service'; // 导入你全局定义的jobQueue实例,也可通过依赖注入方式引入,见下方可选优化 import { jobQueue } from './你的队列实例路径'; @Injectable() export class ClickToCallJob implements IBeeQueueJob<any>{ constructor( private readonly _freeswitchCallSystemService: FreeswitchCallSystemService ){ // 队列处理器和事件监听仅在实例初始化时注册一次,避免重复注册导致的异常 jobQueue.process(async (job, done) => { console.log('jobid', job.id); console.log('result', job.data); // 此处可调用_freeswitchCallSystemService的业务逻辑 done(null, job.id); }); jobQueue.on('succeeded', (job, result) => { console.log('success'); }) } trigger(parameter: any) { // 仅保留任务创建逻辑 return jobQueue.createJob(parameter).save(); } }
2. 业务模块注册Job提供者
在对应的业务模块中,将ClickToCallJob加入providers数组完成注册:
import { Module } from '@nestjs/common'; import { YourController } from './your.controller'; import { ClickToCallJob } from './click-to-call.job'; import { FreeswitchCallSystemService } from './freeswitch-call-system.service'; @Module({ controllers: [YourController], providers: [ FreeswitchCallSystemService, ClickToCallJob ], // 若需要在其他模块使用该Job,可添加导出配置 // exports: [ClickToCallJob] }) export class YourBusinessModule {}
3. 控制器中注入使用
直接在控制器构造函数中注入ClickToCallJob实例,无需手动实例化:
import { Controller, Get, Query } from '@nestjs/common'; import { ClickToCallJob } from './click-to-call.job'; import { CDRModels } from './cdr.models'; @Controller() export class YourController { constructor( private readonly clickToCallJob: ClickToCallJob ) {} @Get('clickToCallStatusCallBack') async clickToCallStatusCallBack(@Query() callData: CDRModels){ console.log('CLICK TO CALL STATUS CALL BACK API', callData); await this.clickToCallJob.trigger(callData); return "Successfully submitted to job queue"; } }
注意:原有代码每次调用
trigger时都会重新注册队列处理器和事件监听,会导致同个任务被多次执行、日志重复打印的问题,改造后这部分逻辑仅会执行一次,符合BeeQueue的使用规范。
可选优化
你可以将BeeQueue实例封装为自定义提供者,避免全局导入,更符合Nest的依赖注入规范,更易测试和维护:
// 模块中注册BeeQueue实例 @Module({ providers: [ { provide: 'BEE_QUEUE_INSTANCE', useFactory: () => { const Queue = require('bee-queue'); return new Queue('你的队列名称', { // 队列配置项,如redis连接配置等 }); } }, // 其他provider ] })
之后在Job类中通过注入的方式获取队列实例:
import { Injectable, Inject } from '@nestjs/common'; import type { Queue } from 'bee-queue'; @Injectable() export class ClickToCallJob implements IBeeQueueJob<any>{ constructor( @Inject('BEE_QUEUE_INSTANCE') private jobQueue: Queue, private readonly _freeswitchCallSystemService: FreeswitchCallSystemService ){ // 初始化逻辑同上 this.jobQueue.process(/* 处理逻辑 */) } }
内容的提问来源于stack exchange,提问作者venalyn sudaria
相关产品推荐
相关产品推荐

