如何使用guzzle发送带有超时限制的并发请求?

6

我正在使用Guzzle 6发送并发请求,如下所示:

public function sendConcurrentRequests() {

    $client = new Client(['timeout' => 5]);

    $promises[] = $client->getAsync('http://example.com/1');
    $promises[] = $client->getAsync('http://example.com/2');
    $promises[] = $client->getAsync('http://example.com/3');

    $results = Promise\unwrap($promises);  

    return $results;
}

每个请求可能需要 1 到 10 秒钟,但我不希望任何请求等待超过 5 秒钟(这就是为什么我设置了超时时间)。我希望的情况是:

  • 请求 1、2 和 3 启动
  • 请求 2 花费的时间超过 5 秒钟,因此请求被取消,并返回及时响应的请求 1 和请求 3 的响应

实际发生的情况如下: - 请求 1、2 和 3 启动 - 请求 2 花费了超过 3 秒钟,因此 unwrap 函数抛出了 ConnectException 异常,我无法得到请求 1 和请求 3 的响应。

我该如何使其正常工作,以便我可以获得及时响应的请求的有效响应?

1个回答

9

在我写完问题之前,我找到了答案,但我仍然想发布它以帮助其他人。

解决方案是用以下调用替换:

$results = Promise\settle($promises)->wait(true);

settle函数不会抛出异常,如果一个promise被拒绝,允许您获取完整的响应数组(包括已完成和已拒绝的响应)。


1
对于任何想要了解与另一个示例的区别的人,请参考:http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=promise#concurrent-requests - The Unknown Dev
2
当这个问题被发布时,该功能尚未记录在文档中,所以我是将其添加到文档中的那个人 :D https://github.com/guzzle/guzzle/commit/812f3a83e5de84a089369ce07452fa9d45d2dd1d - kenske
\GuzzleHttp\Promise\settle($promises)->wait(true); \GuzzleHttp\Promise\settle($promises)->wait(true); - Vasyl Zhuryk
它已经过时了,你应该使用 GuzzleHttp\Promise\Utils::settle。 - Ahmed Aboud
@kenske 您好,感谢更新文档。我想知道如何获取已完成和拒绝的异步请求的正文。谢谢。 - Nipuna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接