typescript - 错误:空响应。没有订阅者监听该消息("x")
我正在尝试通过 Nestjs 和 Nats 创建微服务,但我收到一个错误 Error: Empty response. There are no subscribers listening to that message ("checkUserExists")。目前我只有 Gateway 和 Auth 微服务。所有必要的代码和文件如下所述
网关代码
import { join } from 'path';
import basicAuth from 'express-basic-auth';
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { NestExpressApplication } from '@nestjs/platform-express';
import { Logger, ValidationPipe } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app/app.module';
import { ApiModulesList } from './api/api.modules.list';
import { GlobalExceptionFilter } from './exceptions';
import { swaggerConfig } from './swagger';
const logger = new Logger('Gateway Service');
const bootstrap = async () => {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const configService = new ConfigService();
const port = parseInt(configService.get('API_PORT', '3000'), 10);
const apiRoutePrefix = configService.get('API_ROUTE_PREFIX', 'api');
const apiDoc = configService.get('SWAGGER_DOC_URL', 'api-docs');
const isSwaggerOn = configService.get('IS_SWAGGER_UI_ACTIVE', 'false').toLowerCase() === 'true';
app.useGlobalPipes(new ValidationPipe({ exceptionFactory: (errors) => errors, transform: true, whitelist: true }));
app.useGlobalFilters(new GlobalExceptionFilter());
app.enable('trust proxy');
app.useStaticAssets(join(__dirname, '..', 'public'));
if (isSwaggerOn) {
if (configService.get('NODE_ENV', '') !== 'development') {
app.use(
[`/${apiDoc}`, `/${apiDoc}-json`],
basicAuth({
challenge: true,
users: {
[configService.get('BASIC_AUTH_USER_NAME', 'admin')]: configService.get(
'BASIC_AUTH_PASSWORD',
'Messapps@1'
),
},
})
);
}
const apiGuideLink = configService.get('API_GUIDE_LINK', '');
const appName = configService.get('APPNAME', 'Project name');
const document = SwaggerModule.createDocument(app, swaggerConfig({ appName, port, apiGuideLink }), {
include: ApiModulesList,
});
SwaggerModule.setup(apiDoc, app, document);
}
const natsToken = configService.get('NATS_TOKEN');
const natsHost = configService.get('NATS_HOST', 'localhost');
const natsPort = configService.get('NATS_PORT', '4222');
const natsMicroservice = app.connectMicroservice<MicroserviceOptions>({
transport: Transport.NATS,
options: {
servers: [`nats://${natsHost}:${natsPort}`],
token: natsToken,
},
});
await app.startAllMicroservices();
await app.listen(port);
logger.debug(`API Server started at http://localhost:${port}/${apiRoutePrefix}`);
isSwaggerOn
? logger.debug(`Swagger Docs runs at http://localhost${port ? ':' + port : ''}/${apiDoc} `)
: logger.debug('Swagger Docs is OFF');
};
bootstrap().catch((error) => {
logger.error(error);
});网关服务
import { Inject, Injectable } from '@nestjs/common';
import { CheckUserExistsRequest, CheckUserExistsResponse, AuthSuccessResponse, AuthSignUpRequest } from './dto';
import { AuthType } from './auth.enums';
import { Observable } from 'rxjs';
import { ClientProxy } from '@nestjs/microservices';
@Injectable()
export class AuthService {
constructor(@Inject('GATEWAY_AUTH_PUBLISHER') private natsClient: ClientProxy) {}
checkUserExists(dto: CheckUserExistsRequest): Observable<CheckUserExistsResponse> {
return this.natsClient.send<CheckUserExistsResponse, CheckUserExistsRequest>('checkUserExists', dto);
}
}微服务监听器
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy, MessagePattern } from '@nestjs/microservices';
import { CheckUserExistsRequest, CheckUserExistsResponse } from './dto';
@Injectable()
export class AppService {
constructor(@Inject('AUTH_SERVICE') private natsClient: ClientProxy) {}
@MessagePattern('checkUserExists')
async checkUserExistsRes(dto: CheckUserExistsRequest): Promise<CheckUserExistsResponse> {
console.log('checkUserExistsRes', dto);
return { exists: true };
}
}我已经尝试了所有方法,但没有任何成功,如果有人知道如何解决这个问题,将会非常感激!
答案#1
这个问题是因为 MessagePattern 装饰器被直接用于你的服务中,而不是模块的控制器中。如果装饰器不位于控制器内,将会被忽略
下一个文档说明:
要基于请求-响应模式创建消息处理器,请使用从 @nestjs/microservices 包中导入的 @MessagePattern() 装饰器。该装饰器应仅在控制器类中使用,因为它们是应用程序的入口点。在提供者内部使用它们不会产生任何效果,因为 Nest 运行时会将其忽略。
为了解决你的问题,创建一个控制器来处理请求,并将其传递给服务以处理业务逻辑。
import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
@Controller('app')
export class AppController {
constructor(private readonly appService: AppService) {}
@MessagePattern('checkUserExists')
async handleLoginRequest(dto: CheckUserExistsRequest): Promise<CheckUserExistsResponse> {
return await this.appService.handleLoginRequest(dto);
}
}
