NestJS NATS запрос-ответ - PullRequest
       65

NestJS NATS запрос-ответ

2 голосов
/ 11 июня 2019

Я пытаюсь использовать NestJS и микросервис NATS. Есть хорошая документация для настройки базового запроса-ответа.

Я сделал следующее:

Запустил локальный сервер NATS.

Настройте мой main.ts для подключения к серверу:

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    options: {
      url: "nats://localhost:4222",
    },
    transport: Transport.NATS,
  });
  app.listen(() => console.log("Microservice is listening"));
}
bootstrap();

Создан ClientProxyFactory для отправки обратно сообщений:

export const NatsClientProvider: Provider = {
  inject: [ConfigService],
  provide: NatsClientProviderId,
  useFactory: async (config: ConfigService) =>
    ClientProxyFactory.create({
      options: {
        servers: config.getNatsConfig().servers,
      },
      transport: Transport.NATS,
    }),
};

Настройка контроллера app.controller.ts для ответа на определенный шаблон:

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    @Inject(NatsClientProviderId) private readonly natsClient: ClientProxy,
  ) {}

  @MessagePattern("hello")
  async getHello(data: string) {
    console.log("data: ", data);
    console.log("getHello!!");
    await this.natsClient.send("hello", this.appService.getHello());
    return this.appService.getHello();
  }

  async onModuleInit() {
    await this.natsClient.connect();
    console.log("Nats connected!");
  }

Настройте тестовый файл, чтобы попытаться отправить сообщение запрос-ответ:

import { connect } from "ts-nats";

async function start() {
  const nc = await connect({
    servers: ["nats://localhost:4222"],
  });

  const msg = await nc.request("hello", 5000, "me");
  console.log("msg: ", msg);
}

start();

Когда я запускаю свое приложение Nest, я вижу подпись, созданную правильно в журналах сервера NATS.

Когда я запускаю файл test.ts, он истекает с NatsError: Request timed out.. Тем не менее, я вижу свои журналы консоли (хотя данные undefined, хотя я указываю их в опубликованном сообщении.

Ни методы return, ни client.send не работают для получения сообщений из приложения.

Любая помощь приветствуется!

EDIT: Все еще изучаю и застреваю в этом вопросе. В разделе «Отправка сообщений» Microservice docs говорится: «Шаблон должен быть равен тому, который определен в декораторе @MessagePattern (), в то время как полезная нагрузка - это сообщение, которое мы хотим передать другому microservice. ". Если я это сделаю, приложение Nest обнаружит сообщение, которое оно отправляет, и застрянет в бесконечном цикле отправки сообщения и получения одного и того же сообщения взад и вперед к себе навсегда.

Ответы [ 2 ]

2 голосов
/ 14 июня 2019

Чтобы избежать бесконечного цикла в вашем контроллере, удалите оператор natsClient.send.MessagePattern автоматически отправит ответ с данными, которые вы возвращаете из функции, в вашем случае this.appService.getHello():

@MessagePattern("hello")
async getHello(data: string) {
  console.log("data: ", data);
  return "Hello World!";
}

Nest требует, чтобы вы отправили длинный атрибут id (любая строка подходит) чтобы он мог ответить на сообщение.Просто включите его в данные json:

// Nest expects the data to have the following structure
const reply = await nc.request("hello", 500, JSON.stringify({ data: "Hello", id: "myid" }));
console.log({ reply });

В своем журнале гнезд вы увидите следующую запись:

data: Hello

В своем тестовом скрипте вы увидите это:

{ reply:
   { subject: '_INBOX.GJGL6RJFYXKMCF8CWXO0HB.GJGL6RJFYXKMCF8CWXO0B5',
     sid: 1,
     reply: undefined,
     size: 50,
     data: '{"err":null,"response":"Hello World!","id":"myid"}' 
} }
2 голосов
/ 13 июня 2019

При использовании ClientProxy send и emit возвращают наблюдаемые. Вам нужно «активировать» их, чтобы они что-нибудь сделали. Таким образом, вы можете либо subscribe им, либо заменить его на Обещание.

так как вы используете await вы, вероятно, хотите сделать

await this.natsClient.send("hello", this.appService.getHello()).toPromise();
...