简体   繁体   English

NestJS NATS请求 - 响应

[英]NestJS NATS request-response

I'm trying to use NestJS and the NATS microservice. 我正在尝试使用NestJS和NATS微服务。 There is good documentation for setting up a basic request-response. 有很好的文档可用于设置基本的请求 - 响应。

What I did is the following: 我做的是以下内容:

Ran a local NATS server. 跑一个本地NATS服务器。

Set up my main.ts to connect to the server: 设置我的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();

Created a ClientProxyFactory to send back messages: 创建了一个ClientProxyFactory来发回消息:

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

Set up a controller app.controller.ts to respond to a certain pattern: 设置控制器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!");
  }

Set up a test file to try sending a request-response message: 设置测试文件以尝试发送请求 - 响应消息:

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();

When I run my Nest app, I can see the subscription created properly in the NATS server logs. 当我运行我的Nest应用程序时,我可以在NATS服务器日志中看到正确创建的订阅。

When I run the test.ts file, it times out with NatsError: Request timed out. 当我运行test.ts文件时,它超时NatsError: Request timed out. . However, I can see my console logs (although the data is undefined even though I am specifying it in the published message. 但是,我可以看到我的控制台日志(尽管数据undefined即使我在发布的消息中指定它。

Neither the return nor the client.send methods are working to receive messages back from the app. returnclient.send方法都无法从应用程序接收消息。

Any help is appreciated! 任何帮助表示赞赏!

EDIT: Still looking into and stuck on this issue. 编辑:仍在调查并坚持这个问题。 In the "Sending Messages" section of the Microservice docs , it says "The pattern has to be equal to this one defined in the @MessagePattern() decorator while payload is a message that we want to transmit to another microservice.". 在微服务文档的“发送消息”部分中,它说“模式必须等于@MessagePattern()装饰器中定义的模式,而有效负载是我们想要传输到另一个微服务的消息。” If I do that, the Nest app detects the message it sends and gets stuck in an infinite loop of sending a message and receiving the same message back and forth to itself forever. 如果我这样做,Nest应用程序会检测到它发送的消息并陷入无限循环,即发送消息并永久地来回接收相同的消息。

When using the ClientProxy, send and emit return Observables. 使用ClientProxy时, sendemit返回Observables。 You need to "activate" those for them to do anything. 你需要“激活”那些让他们做任何事情。 So you can either subscribe to them, or change it to a Promise. 因此,您可以subscribe它们,也可以将其更改为Promise。

since you are using await you probably want to do 因为你正在使用await你可能想做

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

To avoid the infinite loop in your controller, remove the natsClient.send statement. 要避免控制器中的无限循环,请删除natsClient.send语句。 MessagePattern will automatically send a reply with the data you return from the function, in your case this.appService.getHello() : MessagePattern将自动发送一个回复,其中包含您从函数返回的数据,在您的情况下为this.appService.getHello()

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

Nest requires you to send a long an id attribute (any string is fine) for it to be able to reply to a message. Nest要求您发送一个长的id属性(任何字符串都可以),以便能够回复消息。 Just include it in the data json: 只需将其包含在数据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 });

In your nest log, you'll see the following log entry: 在您的嵌套日志中,您将看到以下日志条目:

data: Hello

In your test script, you'll see this: 在您的测试脚本中,您将看到:

{ reply:
   { subject: '_INBOX.GJGL6RJFYXKMCF8CWXO0HB.GJGL6RJFYXKMCF8CWXO0B5',
     sid: 1,
     reply: undefined,
     size: 50,
     data: '{"err":null,"response":"Hello World!","id":"myid"}' 
} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM