NestJS NATS 请求-响应

rhl*_*hrm 5 javascript node.js typescript nats.io nestjs

我正在尝试使用 NestJS 和 NATS 微服务。有很好的文档来设置基本的请求-响应。

我所做的是以下内容:

运行本地 NATS 服务器。

设置 mymain.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();
Run Code Online (Sandbox Code Playgroud)

创建了一个 ClientProxyFactory 来发回消息:

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

设置控制器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!");
  }
Run Code Online (Sandbox Code Playgroud)

设置测试文件以尝试发送请求-响应消息:

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();
Run Code Online (Sandbox Code Playgroud)

当我运行 Nest 应用程序时,我可以在 NATS 服务器日志中看到正确创建的订阅。

当我运行test.ts文件时,它超时了NatsError: Request timed out.。但是,我可以看到我的控制台日志(undefined尽管我在发布的消息中指定了数据。

无论是return也不是client.send方法,正在接收消息从应用程序了。

任何帮助表示赞赏!

编辑:仍在调查并坚持这个问题。在微服务文档的“发送消息”部分,它说“模式必须与@MessagePattern() 装饰器中定义的模式相同,而有效负载是我们想要传输到另一个微服务的消息。”。如果我这样做,Nest 应用程序会检测到它发送的消息,并陷入无限循环,发送消息并永远向自己来回接收相同的消息。

Kim*_*ern 5

为了避免控制器中的无限循环,请删除该natsClient.send语句。MessagePattern根据您的情况,将自动发送包含您从函数返回的数据的回复this.appService.getHello()

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

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 });
Run Code Online (Sandbox Code Playgroud)

在您的 Nest 日志中,您将看到以下日志条目:

data: Hello
Run Code Online (Sandbox Code Playgroud)

在您的测试脚本中,您将看到:

{ reply:
   { subject: '_INBOX.GJGL6RJFYXKMCF8CWXO0HB.GJGL6RJFYXKMCF8CWXO0B5',
     sid: 1,
     reply: undefined,
     size: 50,
     data: '{"err":null,"response":"Hello World!","id":"myid"}' 
} }
Run Code Online (Sandbox Code Playgroud)