错误:空响应。没有订阅者正在收听该消息(“x”)

问题描述 投票:0回答:1

我正在尝试通过 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 };
    }
}

我已经尝试了一切,但没有取得任何成功,如果有人知道如何解决这个问题将非常感激!

typescript microservices nestjs messaging messagebroker
1个回答
0
投票

此问题是由于在服务中直接使用 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);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.