Guzzle 池:如何等待所有请求完成而不超时?

Guzzle Pool: how to wait for all requests to finish without timing out?

在过去的 6 个月里,我一直在使用 Guzzle 池从外部服务器请求数据(每次请求大约 1-2 MB)。我同时执行 5 个请求。然而,事情发生了变化,外部服务器似乎超载了,因此变得非常慢。有时它很快就像 1-2 秒,但很多时候服务器需要为每个请求等待 2+ 分钟。

但这应该不是问题。但是现在(因为发出请求变得很慢),我在池中的一些请求返回错误:

cURL error 18: transfer closed with outstanding read data remaining

它通常会在正好等待 2 分钟后执行此操作。

虽然有趣的是,如果我通过 Postman 发出请求(例如),我仍然需要等待 2-3+ 分钟,但我最终得到了响应。

所以这让我相信 Guzzle 在 2 分钟后阻止了请求。但是,我找不到任何设置来更改此设置。我什至尝试发送 Keep AliveContent-Length header,但它们没有用(也许我没有正确使用它们)。

这是我当前执行 Guzzle 池请求的代码的一部分。 (我正在使用 PHP 7.1、Guzzle 6.3 和 Laravel 5.7)。

$headers = ['Authorization' => 'Bearer ' . $token];

$client  = new Client();

$requests = function ($urls, $headers)
{
    foreach ($urls as $key => $url)
    {
        yield new Requests('GET', $url, $headers);
    }
};

$pool = new Pool($client, $requests($urls, $headers),
[
    'concurrency' => 5,
    'fulfilled'   => function ($response, $index)
    {
        echo 'fulfilled -> ' . $index;
    },
    'rejected' => function ($reason, $index)
    {
        echo 'rejected -> ' . $index . ' -> error:' . $reason->getMessage();
    },
]);

$promise = $pool->promise();
$promise->wait();

很遗憾,我无法共享外部服务器 URL,因为它是私有的。

我在这里做错了什么,不允许请求等待它完成/发送数据?


更新: 我已经尝试了@Alexey Shokov 的建议,它摆脱了被拒绝的状态。现在请求不会在 2 分钟后超时。但是,一旦我从以前的 timed out 来源得到一些回复,我就会得到 null 作为响应。

服务器端似乎有问题。该错误表明 cURL 客户端发现服务器发送的预期响应大小与实际响应大小不匹配。

看看this SO topic, same issue. I think it worths trying to set HTTP version to 1.0 as stated in the discussion with Guzzle's version option或者直接在Request对象(yield new Requests('GET', $url, $headers, null, '1.0')).