libcurl: обрабатывать несколько асинхронных запросов в C ++ - PullRequest
0 голосов
/ 17 января 2020

Я работал с easy_perform до сих пор, и он работал как ожидалось. Но из-за тайм-аутов и однопоточного приложения задержка при выполнении нескольких операций. Я смотрю на оптимизацию этих вызовов путем преобразования их в асинхронные с интерфейсом multi_perform, хотя мне трудно понять, как правильно его использовать.

Насколько я понимаю, Flow выглядит примерно так:

  1. Создание easy_handle для вызова

  2. Добавьте этот стандартный простой дескриптор в мульти стек, используя curl_multi_add_handle

  3. curl_multi_perform: Здесь все становится сложнее.

    1. Насколько я понимаю, этот призыв происходит в oop.
    2. Мое приложение вызывает этот API для чтения / записи всего, что есть для чтения или записи, и т. Д. c.
    3. Если running_handles изменяется с предыдущего вызова, есть данные для чтения который мы должны получить, используя curl_multi_info_read
  4. Очистить при обработке легкой ручки

    1. curl_multi_remove_handle
    2. curl_easy_cleanup
    3. curl_multi_cleanup

Q:

  1. Означает ли это, что мое приложение должно выполнять периоды c опрос, чтобы проверить, есть ли данные для чтения?

  2. Есть ли способ справиться с обратными вызовами? и метод обратного вызова должен запускать действие в моем приложении асинхронным способом.

Ссылки, которые я уже рассмотрел:

  1. Просмотр http://www.godpatterns.com/2011/09/asynchronous-non-blocking-curl-multi.html, это говорит то же самое. Поправьте меня, если я ошибаюсь.

  2. поток stackoverflow и другие связанные: Как сделать curl_multi_perform () асинхронно в C ++?

1 Ответ

1 голос
/ 18 января 2020

Необходимые знания, необходимые для понимания API curl_multi: Asyn c Сокеты .

curl_multi_perform не является блокирующим API. Как объяснено в документации:

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

Это просто нужно периодически вызывать.

Означает ли это, что мое приложение должно выполнять период c опрос, чтобы проверить, есть ли данные для чтения?

Да. curl_multi_fdset удобно извлекает соответствующие файловые дескрипторы, чтобы вы могли select на них (select = wait ), но вы можете добавлять другие дескрипторы одного и того же вызова select, таким образом чередуя работу curl с вашей собственной работой. Вот пример того, как это сделать.

Есть ли способ справиться с обратными вызовами?

Да. Переданные данные передаются во время вызова curl_multi_perform в обратный вызов CURLOPT_WRITEFUNCTION . Примечание: curl_multi_info_read не для чтения данных, а для чтения информации о передаче.

  for (/* each transfer */) {
    curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
    curl_easy_setopt(eh, CURLOPT_WRITEDATA, /* pass userp value */);
    curl_multi_add_handle(multi_handle, easy_handle);
  }
  int still_running;
  do {
    if (curl_multi_perform(cm, &still_running)) { // will call write_cb() when data is read
      /* handle error */ break;
    }
    if (curl_multi_wait(cm, NULL, 0, 1000, NULL)) {
      /* handle error */ break;
    }
  } while(still_running);

Вот полный пример использования обратного вызова данных с несколькими перевод: 10-в-время .
Примечание: curl_multi_wait , используемый в этом примере, является удобной оболочкой для вызова select.

...