php - 重用来自 cURL 多处理程序的句柄

标签 php curl

好吧,我试图重用我在初始过程中生成的句柄,但是在第一次运行后它就停止工作了。如果我删除(或重新创建整个处理程序)句柄并再次添加它们,它就可以正常工作。这可能是什么原因造成的?

我的代码目前看起来像这样:

<?php
echo 'Handler amount: ';
$threads = (int) trim(fgets(STDIN));
if($threads < 1) {
    $threads = 1;
}

$s = microtime(true);
$url = 'http://mywebsite.com/some-script.php';

$mh = curl_multi_init();
$ch = array();
for($i = 0; $i < $threads; $i++) {
    $ch[$i] = curl_init($url);
    curl_setopt_array($ch[$i], array(
        CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20130213 Firefox/21.0',
        CURLOPT_REFERER => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_NOBODY => true
    ));

    curl_multi_add_handle($mh, $ch[$i]);
}

while($mh) {
    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while($running > 0);

    $e = microtime(true);
    $totalTime = number_format($e - $s, 2);
    if($totalTime >= 1) {
        echo floor($threads / $totalTime) . ' requests per second (total time '.$totalTime.'s)' . "\r";
        $s = microtime(true);
    }
}

foreach($ch as $handler) {
    curl_multi_remove_handle($mh, $handler);
    curl_close($handler);
}

curl_multi_close($mh);
?>

当我将 CURLOPT_VERBOSE 设置为 true 时,我看到许多“additional stuff not fine transfer.c:1037: 0 0”消息,我在不同的问题,似乎是由一些明显的事情引起的:

  • 太快了

  • 防火墙

  • ISP 限制

据我所知,不是这样,因为如果我每次都重新创建句柄,它们会以每秒大约 79 个请求(每个大约 529 字节)的速度成功完成

我重用句柄的过程:

  1. 创建多处理程序,并向多处理程序添加指定数量的处理程序

  2. 当 mutli handler 工作时,执行所有 handle

  3. 在 while 循环停止后(它似乎不太可能停止),关闭所有句柄和 multi curl 处理程序

它执行一次所有句柄然后停止。

这真让我难堪。有任何想法吗?

最佳答案

我遇到了同样的问题(尽管使用的是 C++),发现我需要删除 curl easy handle(s) 并将其重新添加回去。我的解决方案是删除 curl_multi_perform 循环末尾的所有句柄,并将它们重新添加到外循环的开头,在外循环中我重用现有的保持事件连接:

for(;;) // loop using keep-alive connections
{
    curl_multi_add_handle(...)
    while ( stillRunning ) // curl_multi_perform loop 
    {
        ...
        curl_multi_perform(...)
        ...
    }
    curl_multi_remove_handle(...)
}

也许这也适用于您的 PHP 场景。请记住:不要在 curl_easy_cleanupcurl_easy_init 之间使用 curl 句柄。

如果您打开 CURLOPT_VERBOSE您可以在控制台中进行操作,并且您的连接确实被重用了。这为我解决了这个问题。

关于php - 重用来自 cURL 多处理程序的句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14894783/

相关文章:

curl - 使用 Go 的 POST 失败但适用于 curl

Python 请求 - 上传 Zip 文件

php - 如何在 CodeIgniter 中访问 Controller 类

php - 为什么不使用 PHP 的内置 session 处理?

php - Cakephp Heroku插件路径错误

php - Wordpress 插件 事件日历 - 列出一年内的所有事件

PHP array_sum 输出单个数字而不是整体

curl - 如何通过curl或wget下载Google Drive URL

linux - 更新谷歌纬度

curl - 使用curl进行POST而不发送数据