Подскажите либу для неблокирующих запросов

Тема в разделе "PHP Pro", создана пользователем venetu, 31 мар 2010.

Статус темы:
Закрыта.
  1. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Народ, помогите. Ищу библиотеку, позволяющую параллельно вытягивать несколько HTTP-запросов.

    curl_multi - не совсем то, т.к. ждет окончания всех и только потом возвращает управление, соответственно если у тебя хоть один сервак не отвечает - вся пачка будет висеть и ждать, пока он не отвалится по таймауту.

    Хочется что-то типа onComplete="MyDownloadFinction", т.е. или событийная модель, или на худой конец неблокирующие сокеты, но только в более-менее нормальной обертке к ним, а то вручную писать все эти Host: HTTP1.1\n очень и очень задалбывает. Идеально - чтоб в активный пул запросов можно было самому добавлять "по ходу" новые.

    Наверняка есть уже готовые либы для этого, но что-то гугл их не отдает. Подскажите, профи!
     
  2. lobzik

    lobzik

    Регистр.:
    8 авг 2006
    Сообщения:
    311
    Симпатии:
    49
    Тоже интересовало это, и я знаю как это сделать =) С помощью..... барабанная дробь... мультикурла =) Ага, там есть возможность, но я потерял этот кусок кода, в нем показывалось как вытаскивать уже отработавшие хендлеры =) Так что надо ковырять его дальше ибо альтернатив не так много - писать с использованием сокетов или извращаться с pcntl что немного не верно будет, а еще есть треды.
    UPD. А вот и тот кусок кода
    Код:
    <?php
        $urls = array( «www.example.com/», «www.php.net/» );
        $mh = curl_multi_init();
        $chs = array();
        foreach ( $urls as $url ) {
            $chs[] = ( $ch = curl_init() );
            curl_setopt( $ch, CURLOPT_URL, $url );
            curl_setopt( $ch, CURLOPT_HEADER, 0 );
            // CURLOPT_RETURNTRANSFER - возвращать значение как результат функции, а не выводить в stdout
            curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
            curl_multi_add_handle( $mh, $ch );
        }
        $prev_running = $running = null;
        do {
            curl_multi_exec( $mh, $running );
            if ( $running != $prev_running ) {
                // получаю информацию о текущих соединениях
                $info = curl_multi_info_read( $ghandler );
                if ( is_array( $info ) && ( $ch = $info['handle'] ) ) {
                    // получаю содержимое загруженной страницы
                    $content = curl_multi_getcontent( $ch );
                    // тут какая-то обработка текста страницы
                    // пока пусть будет как и в оригинале - вывод в STDOUT
                    echo $content;
                }
                // обновляю кешируемое число текущих активных соединений
                $prev_running = $running;
            }
        } while ( $running > 0 );
        foreach ( $chs as $ch ) {
            curl_multi_remove_handle( $mh, $ch );
            curl_close( $ch );
        }
        curl_multi_close($mh);
    
     
    KillDead и venetu нравится это.
  3. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Блин, а ларчик-то просто открывался. Даже в каментах на php.net/curl_multi_exec это есть.

    Огромное lobzik спасибо! Для себя я остановился на RollinCurl, (http://code.google.com/p/rolling-curl/) но в принципе такой же подход реально много где используется.

    Странно, что нигде, где рассказывается о том, как юзать мультикурл, об этом нет ни слова.
     
    cybd нравится это.
  4. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    890
    Симпатии:
    558
    Сам недавно смотрел на данный метод, но гугл не выдал ничего хорошего, так что обошёл стороной. А вот сейчас задумался над сабж.
    2venetu RollinCurl сейчас что-то недоступен:confused:. Наверно что-то нашли в новом обнавлении (как раз сегодня залили новую версию). Можешь залить класс куда-нить, хочу хотя бы посмотреть на что это похоже. А то и так придётся половину своей либы подправлять под неблокирующий курл)
     
  5. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Я уже нашел покруче штуку - ParallelCurl.
    Юзаю теперь ее. http://github.com/petewarden/parallelcurl

    Но вообще полезь в CodeSearch по слову CURLM_CALL_MULTI_PERFORM - там их целая куча. EpiCurl, CurlThread, MultiCurl, CurlAsync...

    Реально миллион, аж даже странно что я раньше не мог найти ничего похожего. Я правда, был уверен, что такая штука возможна только на сокетах, и искал в основном про это. А оказывается и curl_multi умеет. Не понятно только, почему такая возможность не идет в нем by default, самому ж ни в жизни не догадаться как такое включить.
     
    KillDead нравится это.
  6. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    890
    Симпатии:
    558
    После попыток заставить нормально работать ParallelCurl и EpiCurl пришёл к выводу, что лучше http://www.nulled.ws/showthread.php?t=120557 нет) Там правда блокирующие соединения. Но это решается не больше чем за 10 строчек.:)
     
  7. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    А можешь скинуть этот Jeurey'ский MultiCurl со своими заветными 10-тью строчками?

    Я лично ParallelCurl супер доволен. Он простой как hello world. Тупо задал кол-во потоков, и он всегда ровно столько соединений и держит. Как какое-нибудь завершилось - пожалуйста, вызывается тебе твой on_request_done, из него можешь смело запускать новый поток. Каждому потоку можно свои опции назначать, вплоть до IP интерфейса, с которого идти.

    Единственное, что в принципе не совсем хорошо (хотя в моем случае устраивает полностью) - это отсутствие окна, т.е. за очередью надо следить самому. Имеется в виду что когда у тебя выполнялось, к примеру, 10 коннектов, один завершился, а ты on_request_done сграббил допустим все ссылки из скачанной html и опять их все добавил в очередь - вот тут уже будет затык, пока место для них всех не освободится, в startRequest() они не влезут. Приходится держать очередь отдельно, но у меня она все равно в базе, т.к. скриптов параллельно висит несколько штук, а очередь общая.

    Так что меня наоборот, ParallelCurl привлек как раз отсутствием наворотов, которые в моем случае все равно реализованы отдельно. Но все равно, за неблокирующий MultiCurl буду благодарен, да наверное и сам Jeurey тоже :)
     
  8. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    890
    Симпатии:
    558
    Запостил в теме бибилиотеки.

    В принципе тоже самое тоже реализовал на классе Jeurey. Позже запостю.
     
  9. lobzik

    lobzik

    Регистр.:
    8 авг 2006
    Сообщения:
    311
    Симпатии:
    49
    cybd и venetu нравится это.
  10. GTAlex

    GTAlex Создатель

    Регистр.:
    2 сен 2008
    Сообщения:
    47
    Симпатии:
    3
    погугли "AunoAsyncHttp" - неблокируемые асинхронные http запросы
     
    venetu нравится это.
Статус темы:
Закрыта.