mcurl отличить поток "обрабатывается" от "сервер недоступен"

KillDead

Хранитель порядка
Регистрация
11 Авг 2006
Сообщения
894
Реакции
579
В общем возникла проблема- есть у меня либа multicurl с неблокирующими соединениями (те готовые соединения удаляются, на их новые приходят новые:(
PHP:
    while (true) {
          
            // Создание потоков
.. code
            // если их меньше чем Количество потоков- открываем и добавляем в $this->_curlMultiHandle новые
 
            curl_multi_select($this->_curlMultiHandle);

            while (($mcRes = curl_multi_exec($this->_curlMultiHandle, $mcActive)) == CURLM_CALL_MULTI_PERFORM) {
                usleep($this->_usleepTime);
            }
 

            while ($threadInfo = curl_multi_info_read($this->_curlMultiHandle)) {
 
             //  Поток $threadInfo['handle'] успешо отработал  ;
             // закрывает его и удаляем из $this->_curlMultiHandle
             ..code
            }
}

Но этот код убивает сервер если пхп меньше 5.2 - функция curl_multi_info_read не работает. И мне надо сделать аналогичный код без использования этой бажной функции. Пока решений не вижу. Сделал первое что взбрело в голову-
PHP:
$mh = curl_multi_init();

foreach ($urls as $i => $url) {

    $conn[$i] = curl_init($url);
  
  curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($conn[$i], CURLOPT_TIMEOUT, 3);
    curl_multi_add_handle($mh, $conn[$i]);

}

do {

    $ready = curl_multi_select($mh);
    $status = curl_multi_exec($mh, $active);

    $info = curl_multi_info_read($mh);

    foreach ($urls as $i => $url) {

        $h = curl_getinfo($conn[$i]);

        if (!$h['http_code']) {
            continue;
        }
        echo "САЙТ загрузился - {$h['url']} \n";
    }

    usleep(1000);
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
те просто в ходе работы запрашиваем информацию о всех потоках, если код ответа не 0, то удаляем поток- он готов. НО! если урл ещё обрабатывается я получаю такой ответ от curl_getinfo
HTML:
 Array
(
    [url] => http://www.bbc.co.uk/
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0
    [namelookup_time] => 0
    [connect_time] => 0
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0
    [redirect_time] => 0
)
а если сервер недоступен, я получаю аналогичный массив
HTML:
Array
(
    [url] => http://www.cnnqqqqqqqqqqq.com/
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0
    [namelookup_time] => 0
    [connect_time] => 0
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0
    [redirect_time] => 0
)
Те получается блокировка- пока не пройдёт пачка положенных в мультикурл соединений- я не могу точно сказать какой поток "обрабатывается" а какой "сервер недоступен".
Как быть? Кто может посвятить на этот вопрос?
 
не очень понял вопрос

второй ответ - после прогона или в процессе опроса? ( если сервер недоступен, то время опроса значительно увеличивается )

а не проще пингануть или другим образом проверить хотя бы доступность хоста, и только потом засовывать адрес в мультикурл?
 
спб что откликнулся :az:

пингануть - не вариант. Я делаю (вернее дописываю) либу, чтобы работала и с не очень старыми версиями. А что же это получается- на каждый запрос мы делаем 2, особенно если работаем через прокси- это расточительно.

не очень понял вопрос
смотри, у меня идея такова-
1) есть мультикул, в него загружается 20 (путь это макс количество) курл объектов,
2) они обрабатываются,
3) как только хотябы 1 получил ответ, мы его закрываем. У нас теперь обрабатывается 19.
4) Тк 19<20 мы добавляем в мультикурл ещё 1 объект. тем самым мы не ждём пока отработает 20 потоков а постоянно держим 20 рабочих потоков

С curl_multi_info_read всё просто - она возвращает тот поток, который Отработал . Но без этой функции - как быть?

второй ответ - после прогона или в процессе опроса? ( если сервер недоступен, то время опроса значительно увеличивается )
Опроса- это где посмотреть? После работы 2 скрипта - я получил массив для недоступного сервера cnnqqqqqqqqqqq.com
Array
(
=> http://www.cnnqqqqqqqqqqq.com/ ...ут то в ней total_time - уже отлично от нуля.
 
даже не знаю чем помочь

ты правда на столько спешишь, что это важно доработать? мне еще ниразу не встречались объемы данных, где это было бы востребованно
 
мне еще ниразу не встречались объемы данных, где это было бы востребованно

ну, я часто пытаюсь сделать всеобъятный скрипт, пренебрегая вещами которые часто могут встретится, но зато будут те, которые практически никогда не произойдут)
Но всё таки , я считаю что 2 коннекта- это черезчур. Особенно прокси- которые дохнут прямо на ходу. Простейший пример- это чекер проксей (на курле наверно это изврат) или накрутчик. А ставить ограничения пхп для скрипта- это можно если скрипт большой. Если для небольшого сайта надо спарсить инфу в 2-4 потока, то кидать им "моя мего либа не поддерживает ваш древний серв" и заставлять их переставлять пхп - не хорошо)

Но проблему решил. Оказалось всё просто)
Вначале я пытался получить какую нибуть информацию с curl_getinfo - не получилось. КаллбекФункции хеадера\прогресса\обработки результата- не получали ничего. Ловил ошибки с помощью curl_errno($curl) - он возвращал что ошибочный курл нормально отработал . Но CURLOPT_STDERR писал ошибку курла в файл, уже хотел создать сокет и прослушивать на предмет ошибки , но обошлось - curl_error() - он нормально сообщает об ошибке если она произошла - Could not resolve host: cnnqqqqqqqqqqq.com; Host not found
 
я рано обрадовался, оказывается как только получен заголовок, массив от curl_getinfo
HTML:
Array
(
    [url] => http://ereg/proekt/pi_multicurl/test/chek.php?x=size
    [content_type] => text/html
    [http_code] => 200
    [header_size] => 175
    [request_size] => 138
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.499
    [namelookup_time] => 0
    [connect_time] => 0.016
    [pretransfer_time] => 0.016
    [size_upload] => 0
    [size_download] => 2096959
    [speed_download] => 4202322
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0.016
    [redirect_time] => 0
    [request_header] => GET /proekt/pi_multicurl/test/chek.php?x=size HTTP/1.1
User-Agent: Opera/7.50 (Windows ME; U) [en]
Host: ereg 
Accept: */*
)
выдаётся даже если курл не завершил работу. Т.е. теперь проблема другая возникла- как опредлелить- завершил работу объект или нет? Есть варинты?
 
Назад
Сверху