在服务器端完成某些处理之前,如何保持或休眠http请求?

时间:2019-01-24 13:55:16

标签: java .net node.js http

我有一个Web应用程序。 UI客户端触发对服务器的http请求。 服务器必须在发送响应之前将响应保留几秒钟。保留时间-是用于联系其他一些第三方服务的。我们向第三方服务发送请求,并每1秒轮询几秒钟,以查看某些特定状态。此循环结束后,再发送UI客户端的响应。 所以

var state = send request to third party
while(state = "poll" ) {
   do I need to sleep the current thread like sleep(currentThread, 1sec) ? 
   call third party again to know the state.
}

开发人员通常如何做到这一点? 如果我们阻止当前的http线程,则对整个服务器没有任何影响。是否会对其他请求造成任何问题。

  1. www.test.com
  2. 输入用户名和密码-POST
  3. 服务器在其本地数据库中进行验证, 向第三方应用发送请求以获取与其用户名相关的一些报价。
    1. 创建报价请求-收到状态为“正在准备”的响应
    2. 获取报价-“准备就绪”
    3. 等待/睡眠1秒
    4. 获取报价-“准备就绪”
    5. 等待/睡眠1秒
    6. 获取报价-“准备就绪”
    7. 等待/睡眠1秒
    8. 获取报价-“完成”
  4. 将响应发送为JSON。

可以用不同的方式完成同样的操作。

  1. www.test.com
  2. 输入用户名和密码-POST
  3. 服务器在其本地数据库中进行验证, 向第三方应用发送请求以获取与其用户名相关的一些报价。
    1. 创建报价请求-收到状态为“正在准备”的响应
    2. 将request_id存储在数据库中。
  4. 将响应发送为JSON
  5. 使用request_id轮询服务器
  6. “准备就绪”
  7. setTimeout(1sec)
  8. 使用request_id轮询服务器
  9. “准备就绪”
  10. setTimeout(1sec)
  11. 使用request_id轮询服务器
  12. “准备就绪”
  13. setTimeout(1sec)
  14. 使用request_id轮询服务器
  15. “完成”

这两种情况有所不同。

第一个,我不是每秒都用http调用充斥我的Web服务器。而是我先持有http请求,然后等待来自定量服务的响应,然后处理响应。 我的问题是我如何才能使请求线程保持或使该请求线程以1秒的频率休眠。

第二个是连续的轮询,它将淹没Web服务器。

3 个答案:

答案 0 :(得分:1)

我认为您的方法很有趣,但远非有效。开发Web应用程序时,有更优雅的方法来报告过程状态。例如看一下SignalR或SocketIO。这样,您不必维护与服务器的开放连接,而是将工作状态推送给客户端。

答案 1 :(得分:0)

Node.js本质上是单线程的,我们使用Promises等待直到未收到其他第三方服务的响应。

async function apiController(req, res){
      const response = await request.get('http://...........)
      res.status(200).json({...})

此函数基本上在eventLoop中等待以从上述api调用中获取响应,从而允许主线程空闲并用于其他任务

答案 2 :(得分:0)

问题的几个方面:

(1)您的Web服务器可以这样做吗?是的,当然很容易。任何流行的HTTP服务器框架(例如ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS'; ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF9'; )都使用异步回调来处理请求/响应。因此,您可以轻松地不发送响应,直到您从第三方API收到所需的信息为止。

使用带有express的promise的伪代码示例

express

(2)您应该这样做吗?实际上,在等待第三方API响应时,向Web服务器发出的请求阻止的情况很常见-但是,您需要注意这一点。超过750毫秒的响应时间将被许多用户认为是缓慢的。因此,您确实希望任何给定的第三方API响应都达到100-400ms的峰值。如果您打算在此上旋转数秒,那么另一种方法可能会更好。

(3)您还有其他选择吗?

请考虑此第三方请求最多可能需要30分钟才能完成。您将如何在应用程序中处理此问题?常见的方法是这样:

app.get('/myurl', function (req, res) {
    makeApiRequest().then(result => {
        // We reach here after we are all done with the API.
        res.send('here is a response to browser using data from result');
    });
});

async function makeApiRequest() {
    // here, make the API request, do a polling loop, etc.
    // eventually return the result
}

用户体验取决于应用程序。如果用户上载了要处理的大型XML文件,并且等待时间为2-3分钟,那么您可能希望他们坐在页面上,同时进度条会慢慢填充。

一种不同的体验是用户可以离开并随意返回的页面,这更像是他们提交的申请表(他们正在检查创建新DNS记录的请求状态)例如,已经完成)。

无论哪种方式,您都在幕后进行了设置,以便您的 server 仅接受“开始请求”和“检查请求”调用,这是您写入的客户端代码做循环。

相关问题