Jak wykonać curl multi perform () asynchronicznie w C++?

Przyszedłem użyć curl synchronicznie robiąc żądanie http. Moje pytanie brzmi: Jak mogę to zrobić asynchronicznie?

Przeprowadziłem kilka poszukiwań, które doprowadziły mnie do dokumentacji interfejsu curl_multi_* z tego pytania i tego przykładu, ale nic nie rozwiązało.

Mój uproszczony kod:

CURLM *curlm;
int handle_count = 0;
curlm = curl_multi_init();

CURL *curl = NULL;
curl = curl_easy_init();

if(curl)
{
    curl_easy_setopt(curl, CURLOPT_URL, "https://stackoverflow.com/");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_multi_add_handle(curlm, curl);
    curl_multi_perform(curlm, &handle_count);
}

curl_global_cleanup();

Metoda callback writeCallback nie jest wywoływana i nic się nie dzieje.

Proszę mi doradzić.

EDIT:

Według @Remy poniżej odpowiedź, mam to, ale wydaje mi się, że to nie jest to, czego naprawdę potrzebowałem. Ponieważ używanie pętli jest nadal blokowaniem. Proszę powiedz mi, czy robię źle lub coś źle. Jestem całkiem nowy w C++.

Tu znowu mój kod:

int main(int argc, const char * argv[])
{
    using namespace std;
    CURLM *curlm;
    int handle_count;
    curlm = curl_multi_init();

    CURL *curl1 = NULL;
    curl1 = curl_easy_init();

    CURL *curl2 = NULL;
    curl2 = curl_easy_init();

    if(curl1 && curl2)
    {
        curl_easy_setopt(curl1, CURLOPT_URL, "https://stackoverflow.com/");
        curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_multi_add_handle(curlm, curl1);

        curl_easy_setopt(curl2, CURLOPT_URL, "http://google.com/");
        curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_multi_add_handle(curlm, curl2);

        CURLMcode code;
        while(1)
        {
            code = curl_multi_perform(curlm, &handle_count);

            if(handle_count == 0)
            {
                break;
            }
        }
    }

    curl_global_cleanup();

    cout << "Hello, World!\n";
    return 0;
}

Mogę teraz wykonywać 2 żądania http jednocześnie. Wywołania zwrotne są wywoływane, ale nadal muszą zostać zakończone przed wykonaniem następujących linii. Czy będę musiał myśleć o wątku?

Author: Community, 2014-06-18

1 answers

Przeczytaj jeszcze raz uważnie dokumentację, szczególnie te fragmenty:

Http://curl.haxx.se/libcurl/c/libcurl-multi.html

Twoja aplikacja może zdobyć wiedzę z libcurl, kiedy chce zostać wywołana w celu przesłania danych, dzięki czemu nie musisz wykonywać pętli zajętości i wywoływać tego curl_multi_perform(3) jak szalony. curl_multi_fdset (3) oferuje interfejs, za pomocą którego można wyodrębnić fd_sets z libcurl do użycia w select () lub poll() wywołuje w celu sprawdzenia, kiedy transfery w stosie multi mogą wymagać uwagi. To również sprawia, że bardzo łatwo programowi czekać na wejście na własnych deskryptorach plików w tym samym czasie lub być może timeout co jakiś czas, jeśli chcesz, że.

Http://curl.haxx.se/libcurl/c/curl_multi_perform.html

Gdy aplikacja dowie się, że są dostępne dane dla multi_handle lub upłynął limit czasu, aplikacja powinna wywołać tę funkcję do odczytu / zapisu cokolwiek jest do odczytu lub zapisu w tej chwili itd. curl_multi_perform () zwraca natychmiast po zakończeniu odczytu/zapisu. Funkcja ta nie wymaga, aby rzeczywiście były dostępne dane do odczytu lub że dane mogą być zapisywane, może być wywołana na wszelki wypadek. Zapisuje liczbę uchwytów, które nadal przesyłają dane w wskaźniku całkowitym drugiego argumentu.

Jeśli Ilość running_handles zostanie zmieniona z poprzednie wywołanie (lub jest mniejsze niż ilość łatwych uchwytów dodanych do wielu uchwytów), wiesz, że jest jeden lub więcej transferów mniej "uruchomionych". Następnie można wywołać curl_multi_info_read(3) , aby uzyskać informacje o każdym zakończonym transferze, a zwrócone informacje zawierają CURLcode i inne. Jeśli dodany uchwyt zawiedzie bardzo szybko, nigdy nie może być liczony jako running_handle.

Gdy running_handles {[29] } jest ustawione na zero (0) po zwróceniu tego funkcja, nie ma już żadnych transferów w toku.

Innymi słowy, musisz uruchomić pętlę, która sprawdza status libcurla, wywołując curl_multi_perform(), gdy są dane oczekujące na przesłanie, powtarzając je w razie potrzeby, dopóki nie zostanie nic do przesłania.

Artykuł na blogu podlinkowałeś do tej strony:

Kod może być użyty jak

Http http;
http:AddRequest (" http://www.google.com");

// w pewnej pętli aktualizacji o nazwie każda klatka
http:Update();

Nie robisz pętli w swoim kodzie, dlatego nie jest wywoływany oddzwanianie. Nowe dane nie zostały jeszcze odebrane, gdy wywołujesz curl_multi_perform() jeden raz.

 8
Author: Remy Lebeau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-18 15:15:58