libcurl: как работает соединение Keep-Alive? - PullRequest
1 голос
/ 10 февраля 2020

Как мне сохранить соединение с libcurl?

Я хотел бы использовать следующее. Я хочу подключиться к серверу, который поддерживает Keep-Alive, но который закрывает соединение после 90 секунд бездействия. Я хочу делать POST время от времени, когда происходят некоторые события (вне этого соединения), и я хочу поддерживать соединение в активном состоянии, чтобы уменьшить задержку. Может случиться, что в течение более 90 секунд не будет происходить никаких событий, поэтому я хочу, чтобы сервер сказал, что я не бездействую.

Страница примеров отличная, но я не вижу ни одной, включающей Keep-Alive: https://curl.haxx.se/libcurl/c/example.html

Я нашел CURLOPT_TCP_KEEPINTVL: https://curl.haxx.se/libcurl/c/CURLOPT_TCP_KEEPINTVL.html, но мне не ясно, как это должно работать. В этом примере мы видим код:

CURL *curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");

  /* enable TCP keep-alive for this transfer */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);

  /* set keep-alive idle time to 120 seconds */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L);

  /* interval time between keep-alive probes: 60 seconds */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);

  curl_easy_perform(curl);
}

В описании сказано следующее:

Pass long. Устанавливает интервал в секундах, в течение которого операционная система будет ожидать между отправкой проб проверки активности. Не все операционные системы поддерживают эту опцию. (Добавлено в 7.25.0)

Два вопроса:

A) Как мне это использовать? Из описания похоже, что пока я держу curl в области видимости, соединение останется открытым. Это правильно? И тогда я должен просто продолжать делать

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
res = curl_easy_perform(curl);

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

B) Что это за тесты keepalive и где я могу прочитать о них больше? Это то, что ОС делает за моей спиной? Должен ли я думать об этом как: с точки зрения моего приложения, соединение магически живо, и мне не стоит об этом беспокоиться?


Да, я имел в виду HTTP Keep-Alive, извините за Неоднозначность.

Со вчерашнего дня я обнаружил, что сам Даниэль Стенберг ответил на аналогичный вопрос здесь: { ссылка }

Это отвечает части А) моего вопроса. Но это не отвечает на вопрос B). Мне также нужно знать: если по какой-либо причине соединение выполняет d ie, как мне это обнаружить? Или libcurl позаботится о переподключении?

Кто-то может смело редактировать это в моем исходном сообщении.

1 Ответ

2 голосов
/ 11 февраля 2020

постоянные соединения HTTP

Как уже много раз говорилось: libcurl по умолчанию делает постоянные соединения HTTP. Вам просто нужно повторно использовать ручки для завитков, чтобы это работало, и вы должны активно просить , а не делать их постоянными, если вы не хотите их. Неважно, какой метод HTTP вы используете. GET, POST, HEAD и т. Д. c поддерживают соединение - если только не произойдет что-то необычное.

Современные версии libcurl, тем не менее, будут повторно использовать соединения только до CURLOPT_MAXAGE_CONN секунд (118 по умолчанию) - поскольку вероятность успешного повторного использования со временем очень быстро уменьшается.

Иногда вы видите, что клиенты используют заголовок Keep-Alive:, но это наследие дней HTTP / 1.0 и практически бессмысленно в наши дни.

Если соединение закрывается через 90 секунд, как указано в этом вопросе, то это потому, что сервер закрывает незанятые соединения. Серверы делают это. Вы не можете предотвратить их каким-либо иным способом, кроме как снова использовать соединение до того, как его уничтожит сервер.

TCP Keepalive

Параметры поддержки TCP на совершенно другом уровне. В основном это TCP, отправляющий пакет по соединению после N секунд бездействия, чтобы убедиться, что соединение остается активным (и обнаруживать разорванные соединения).

libcurl не включает поддержку активности TCP по умолчанию, см. CURLOPT_TCP_KEEPALIVE .

...