【问题标题】:Limit connecting time with Guzzle HTTP PHP client使用 Guzzle HTTP PHP 客户端限制连接时间
【发布时间】:2014-01-17 19:35:36
【问题描述】:

我正在使用 Guzzle 打开一个 url-s 列表并获取标题。有些网址响应时间过长,无法打开,我想忽略它们。在 Guzzle 引发异常之前,我最多需要 20 多秒,我想更改它并将连接时间限制为 2 秒。我有这段代码,但仍然需要更长的时间:

<?php
include 'vendor/autoload.php';

$start = new \DateTime("now");

$start = $start->format("d.m.Y H:i:s");
echo $start."\n";
$client = new Guzzle\Http\Client();

Guzzle\Http\StaticClient::mount();

try {
    $request = $client->get('http://takestoolongexample', [], ['connect_timeout' => 2, 'timeout' => 3, 'debug' => true]);
    $response = $request->send();

    var_dump($response->getStatusCode());
} catch (Exception $e) {
    echo "\n".$e->getMessage()."\n";
}

$end = new \DateTime("now");

$end = $end->format("d.m.Y H:i:s");

echo "\n".$end."\n";
?>

这是一个示例结果。如您所见,耗时 13 秒。

$ php test.php
30.12.2013 22:00:07
* getaddrinfo(3) failed for takestoolongexample:80
* Couldn't resolve host 'takestoolongexample'
* Closing connection 0

[curl] 6: Couldn't resolve host 'http://takestoolongexample' http://takestoolongexample

30.12.2013 22:00:20

http://takestoolongexample 是一个真实的网址,在这里更改)

【问题讨论】:

    标签: php guzzle


    【解决方案1】:

    这是 Guzzle 版本 (Guzzle 4) 的此问题的更新解决方案。

    $request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url), [
        'timeout' => 5, // Response timeout
        'connect_timeout' => 5, // Connection timeout
    ]);
    

    抛出Guzzle\Http\Exception\RequestException

    最新版本的文档在这里:Guzzle request options - connect_timeouttimeout

    【讨论】:

      【解决方案2】:

      在使用 guzzle 客户端之前设置 dns 解析超时

      putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1'); //dns resolve params
      
      $request = $client->get(sprintf("%s/noisesize.api", $this->noiseConfig->url), 
      array(
      'timeout' => 5, // Response timeout
      'connect_timeout' => 5, // Connection timeout
      ));
      

      【讨论】:

        【解决方案3】:

        小精度, 您还可以在客户端构造函数上定义超时

        $client = new Guzzle\Http\Client('', array(
            'request.options' => array (
                'timeout' => 6,
                'connect_timeout' => 6 
            ) 
        ));
        

        此客户端发出的所有请求均有效

        【讨论】:

        【解决方案4】:

        我知道如何在 Guzzle 中做到这一点的唯一方法是:

        $params = array(
            'command.request_options' = array(
                'timeout'         => 5,
                'connect_timeout' => 2
            )
        );
        
        $client = new Client();
        
        $description = ServiceDescription::factory('/path/to/service/description/file');
        $client->setDescription($description);
        
        $command = $client->getCommand('commandName', $params);
        $command->prepare();
        
        $client->execute($command);
        

        乍一看,Guzzle 的文档似乎非常好,但我认为它很差,令人困惑且不完整。所以,对我来说,很难弄清楚你的代码是否真的正确以及它是否应该工作。

        【讨论】:

          【解决方案5】:

          你的例子是正确的,但它总是会失败。

          错误发生在 cURL 级别,而不是 Guzzle。在发送 HTTP 请求(Guzzle 的工作)之前,您需要建立相关的 IP 会话(cURL 的一个)。要获得 IP 会话,必须在发送数据包之前进行 DNS 转换。

          在您的示例中,DNS 解析失败。它发生在 cURL 代码中,而不是 Guzzle 代码中。所以你的超时值不会被使用。

          如果您的真实 URL 仍然存在此错误,您可以在您的 guzzle 请求之前添加一个测试,以检查 DNS 是否已解析。或者您可以定义以下 cURL 选项:CURLOPT_CONNECTTIMEOUT 或 CURLOPT_CONNECTTIMEOUT_MS(参见http://php.net/manual/en/function.curl-setopt.php

          【讨论】:

            猜你喜欢
            • 2012-08-17
            • 1970-01-01
            • 2023-03-14
            • 1970-01-01
            • 1970-01-01
            • 2016-06-17
            • 1970-01-01
            • 2016-03-31
            • 1970-01-01
            相关资源
            最近更新 更多