如何管理基于消息队列侦听器(NodeJS)的并行HTTP请求

时间:2019-02-23 08:46:21

标签: node.js http asynchronous microservices mqtt

我确定这种问题已经在这里解决了很多次,但是我找不到这些问题的表达方式。

我有一个微服务,用于处理基础架构与MQTT Broker之间的通信。每次收到HTTP请求时,我都会发送“谁在房间XXX中还活着?”。 MQTT Broker上显示一条消息,并且每个在“ XXX / alive”主题上注册的客户端都必须回答,我等待Y毫秒,然后再通过将收到的响应发送回客户端来关闭请求。

当我处理一个请求时,它工作得很好。但是,一次要一个以上的请求时,它就搞砸了。

这是处理HTTP请求的Express路由:

app.get('/espPassports', (req, res) => {
  mqttHelper.getESPPassports(req.query.model_Name).then((passports) => {
    res.send(passports).end();
  }).catch(err => {
    res.send(err).end();
  })
})

getESPPassports的工作原理如下:

getESPPassports: async (model_Name) => {
    return new Promise((resolve, reject) => {
      // Say there is a request performed
      ongoing_request.isOpen = true;
      ongoing_request.model_Name = model_Name;
      //  Ask who is alive
      con.publish(topic, "ASK");
      setTimeout(() => {
      // If no answer after given timeout
        if (ongoing_request.passports.length == 0) {
          reject({ error: "No MQTT passports found" });
      // Else send a deep clone of the answers (else it's empty)
        } else {
          resolve(JSON.parse(JSON.stringify(ongoing_request.passports)));
        }
      // Delete the current request object and 'close it'
        ongoing_request.passports.length = 0;
        ongoing_request.isOpen = false;
        ongoing_request.model_Name = ""
      }, process.env.mqtt_timeout || 2000)
    })
  }
};

这是MQTT侦听器:

con.on("message", (topic, message) => {
      // If a passport is received check the topic and if there is a request opened
      if (_checkTopic(topic) && ongoing_request.isOpen) {
        try {
          ongoing_request.passports.push(JSON.parse(message));
        } catch (error) {
      // do stuff if error
        }
      }
  }
})

我知道问题出在我用来指定是否有正在进行的请求的布尔值中,我正在考虑为每个新请求创建一个对象,并通过唯一的ID(例如时间戳)来标识它们。无法使MQTT监听器知道此唯一ID。

我还有其他解决方案,但是我不确定它们是否会起作用,我觉得有一种方法可以很好地处理我不知道的问题。

祝你有美好的一天。

1 个答案:

答案 0 :(得分:0)

您需要为每个请求生成一个唯一ID,并将其包含在MQTT消息中,然后可以缓存以该唯一ID作为键的Express响应对象。

设备需要在响应中包含唯一ID,以便将它们与正确的响应配对。

另一种方法是仅缓存来自设备的响应,并为缓存分配生存时间,因此您无需每次都询问设备。