我正在尝试通过 Nestjs 和 Nats 创建微服务,但出现错误
Error: Empty response. There are no subscribers listening to that message ("checkUserExists")
现在我只有网关和身份验证微服务
下面描述了所有必需的代码和文件
网关代码
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 };
}
}
我已经尝试了一切,但没有取得任何成功,如果有人知道如何解决这个问题将非常感激!
此问题是由于在服务中直接使用 MessagePattern 装饰器而不是模块控制器造成的。如果装饰器不在控制器内,它将被忽略
嵌套文档状态:
要创建基于请求-响应范例的消息处理程序,请使用 @MessagePattern() 装饰器,它是从 @nestjs/微服务包。该装饰器只能使用 在控制器类中,因为它们是您的入口点 应用。在提供商内部使用它们不会产生任何影响,因为它们 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.sendLoginLink(data);
}
}