【问题标题】:can a node express request be saved to memory? or other way to suspend a request and wait for another request可以将节点快速请求保存到内存中吗?或其他方式暂停请求并等待另一个请求
【发布时间】:2018-03-02 19:03:08
【问题描述】:

我们在我们的节点应用程序中使用 express,它包装了一个网络服务,以通过我们的服务提供商发送文本消息,流程如下:

客户端应用程序(网络应用程序或其他节点应用程序)请求以电话号码和消息正文作为参数发送文本消息。

我们的节点应用会将请求转发给我们的短信服务提供商,给客户端的参数我们添加一个我们在发送请求之前生成的 uuid。

然后,服务提供商将通过成功接受消息或任何其他可能发生的错误(错误的电话号码、空消息等)来回复我们的请求。

我们现在可以将请求状态、成功或失败(有原因)返回给客户端进行处理。

以上所有内容都很好,这是有趣的部分。

由于我们对服务提供商的请求的响应仅表明请求已被接受,因此我们最终会从服务提供商那里收到另一个请求(POST 请求),无论消息是否已实际发送。这也将保存我们提供请求的 uuid,以便我们可以处理正确的消息。这将在第一次响应我们的请求后 5-10 秒到达。

现在,我们想让客户端的应用程序询问我们消息是否真的发送了。 因此,一旦他们收到我们对消息已接受的第一个响应,我们也会返回带有该响应的 uuid,他们现在可以使用该 uuid 发送另一个请求来询问我们的状态。

如果我们收到服务提供者通知,我们想使用 uuid 作为键将该通知缓存在内存中。这样当客户端请求到达时,我们将缓存。获取状态和响应。

问题是,在大多数情况下,客户端会在服务提供者发送通知之前要求验证,这意味着当客户端请求到达时,我们仍然没有从服务提供者那里得到状态。

在我看来,有两个选项可以解决这个问题:

  1. 通过找到一种方法来保存来自客户端的请求(不确定是否可能,内存?),直到来自文本消息服务提供商的 POST 请求到达并在 ref id 匹配时将其拉出,然后返回回复客户。

  2. 一旦客户端验证请求进入路由,调用将返回新承诺的函数。这只会在 POST 请求到达时解决,它可能需要每隔几秒钟左右迭代一次,并检查是否存在具有相同 ref id 的 POST,然后才解决承诺,然后将响应返回给客户端。这可能会有一两分钟的超时,因此客户端的请求不会只是超时。

我们已经搜索了几天,但没有找到任何类似的用例或解决方案。

我很清楚我们可以使用套接字来做到这一点,但这感觉太过分了,我们希望让这个应用程序简单明了。

感谢您的回答。 谢谢。

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    所以流程是:

    1. 您收到客户请求
    2. 您回复“接受”
    3. 您向提供商发送请求
    4. 他们回复“接受”
    5. 一段时间后,他们向您发送了一个请求,说“结果如下”
    6. 客户端页面会定期请求更新状态

    • 请求具有 UUID

    鉴于以上所有情况,实际上非常简单如果只有一个 Node 实例为您的应用提供服务:使用 Map 的请求:

    1. 有一张客户请求的地图:

      const clientRequests = new Map();
      
    2. 当你收到客户请求时添加它

      const clientRequests.set(theUUID, {
          UUD:     theUUID,
          created: Date.now(),
          status:  "pending"
      });
      
    3. 当提供者回复时更新它:

      const request = clientRequest.get(theUUID);
      if (request) {
          request.response = /*...*/;
          request.status = "complete";
      }
      
    4. 当客户询问时检查它

      const request = clientRequests.get(theUUID) || {status: "invalid"};
      // ...use request.status and potentially request.response...
      

      ...如果回复“完成”,可能会将其删除:

      if (request.status == "complete") {
          clientRequests.delete(theUUID);
      }
      

    您可能希望定期循环遍历地图以清理您从未收到响应的旧请求(这就是我包含created 属性的原因)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 2021-05-11
      相关资源
      最近更新 更多