PHP: http GET/POST действительно асинхронно

В принципе, я ищу способ сделать следующее в PHP:

http_get_or_post('an.url', 'or.two');

// Do some work here, not worrying about the http going on in the background.

$r = wait_for_and_get_the_results_of_the_http_requests()

И, возможно, кто-то с большим опытом работы с завитками может подтвердить, что curl_multi — это то, что я ищу.

Из того, что я узнал из http://php.net/manual/en/function.curl-multi-init.php, пример может дать мне то, что мне нужно:

$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch1);

$active = null;
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

// Now, am I free to do some time consuming work here and not worry about
// calling curl_multi_exec every now and then to facilitate the background
// http / socket processes?

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

curl_multi_remove_handle($mh, $ch1);
curl_multi_close($mh);

Теперь главный вопрос: правильно ли я понимаю, что это будет делать?

1) Первый цикл будет заниматься только отправкой/записью запросов в сокеты.

2) Все вещи, связанные с http/socket, будут происходить в фоновом режиме после того, как запросы будут отправлены, что дает мне возможность делать другие вещи без необходимости периодически вызывать curl_multi_exec, чтобы убедиться, что какой-то буфер где-то не заполнен и нуждается в пинке, чтобы сохранить собирается.

3) Второй цикл будет ожидать поступления любых ожидающих ответа данных и заканчивать чтение и обработку ответов.

Теперь это все еще не будет полностью асинхронным - я могу заблокироваться при записи запросов, если буферы записи сокета заполнятся, но в моем сценарии это не проблема, я беспокоюсь только о том, чтобы вызвать curl_multi_exec, пока я делаю остальные вещи посередине, просто чтобы все это не зависло до следующего шанса, когда я вызову curl_multi_exec.

Я также согласен с тем, что это относится к общему сценарию ответов 2k-4k, когда более крупные ответы застревают в фоновом режиме, пока я не доберусь до второго цикла.

Так работает curl_multi? Если нет, что вы можете предложить, чтобы сделать это на PHP?


person DeducibleSteak    schedule 20.08.2013    source источник


Ответы (2)


curl_multi выполняет свою работу понемногу. Каждый вызов curl_multi_exec выполняет небольшой фрагмент операции передачи, и как только вы вызвали его достаточное количество раз, а данные были отправлены и получены, это делается.

person Daniel Stenberg    schedule 20.08.2013

Только что сделал несколько тестов, и вкратце - нет, это не так, как это работает с curl_multi - вам нужно продолжать вызывать curl_multi_exec, без этого первый цикл сможет только выполнить рукопожатие TCP для соединения, даже не отправить запрос.

Обидно, mysqli с помощью mysqlnd может выполнять асинхронные запросы, почему не может curl?

person DeducibleSteak    schedule 20.08.2013