Простой способ "подтолкнуть" сервер, чтобы держать соединение открытым? - PullRequest
3 голосов
/ 30 мая 2019

Хорошо, небольшой контекст: у меня есть приложение, работающее во встроенной системе, которое отправляет несколько разных запросов по HTTP (используя libcurl в C ++) через следующие интервалы: 5 минут 15 минут 1 час 24 часа

Моя цель: снизить потребление данных (работает по сотовой сети)

У нас есть TLS-аутентификация как на стороне клиента, так и на стороне сервера, поэтому рукопожатие обходится дорого.Идея состоит в том, что мы используем постоянные соединения (по крайней мере, для файлов с более коротким интервалом), чтобы не делать рукопожатие каждый раз.

К сожалению, после долгих попыток я выяснил, что сервер закрывает соединение до того, какинтервалы проходят.Может быть, это то, что мы можем расширить?Мне придется поговорить с парнями на стороне сервера.

У меня сложилось впечатление, что именно по этой причине существовали пакеты "TCP keep-alive", но якобы те, что "проверяют соединение", не "держат его открытым."как следует из названия.

Моя идея такова:

Пусть мое приложение отправляет пакет (как можно меньшего размера) каждые 2 минуты или около того (как бы долго ни было время ожидания), чтобы" подтолкнуть "«связь остается открытой.

Мои вопросы:

  1. Имеет ли это какой-то смысл?
  2. Не думаю, что есть простой способ сделатьэто в libcurl есть?
  3. Если да, то как мало мы можем получить запрос?
  4. Есть ли еще более простой способ сделать это?Моя единственная проблема здесь заключается в том, что все компоненты соединения «живут» в libcurl.

Спасибо!

1 Ответ

2 голосов
/ 31 мая 2019

Было бы проще дать более точный ответ, если бы вы немного подробнее описали архитектуру своего приложения.Например, это RESTful API?Является ли использование HTTP абсолютно обязательным?Если да, то какой HTTP-сервер вы используете (nginx, apache, ...)?Можете ли вы рассматривать веб-сокеты в качестве альтернативы простому HTTP?

Если вы можете использовать что-то кроме обычного HTTP или HTTP - и использовать что-то отличное от libcurl на стороне клиента - у вас будет большеoptions.

Если, с другой стороны, если вы ограничены обоими

  1. , используйте HTTP (а не необработанное TCP-соединение или веб-сокеты) и
  2. используйте libcurl

, тогда я думаю, что ваша задача немного сложнее, но, возможно, все еще возможна.

Одна из ваших первых проблем состоит в том, что типичные таймауты для соединения HTTP довольнонизкий (всего несколько секунд для Apache 2).Если вы можете настроить сервер, вы можете увеличить его.

У меня сложилось впечатление, что именно по этой причине существовали пакеты TCP keep-alive, но якобы те, которые "проверяют соединение", не сохраняютон открывается ", как следует из названия.

Ваша терминология здесь неоднозначна.Вы имеете в виду пакеты поддержки активности TCP или постоянные HTTP-соединения?Они не обязательно имеют какое-либо отношение друг к другу.Первый является необязательным механизмом в TCP (который по умолчанию отключен).Последний является концепцией прикладного уровня, которая специфична для HTTP - и может использоваться независимо от того, используются ли пакеты поддержки активности на транспортном уровне.

Моя единственная проблема заключается в том, что всештука "живет" в libcurl.

Проблема с использованием libcurl заключается в том, что она в первую очередь передает библиотеку.Я не думаю, что он предназначен для длительных и постоянных соединений TCP.Тем не менее, по словам Даниэля Стенберга (автора libcurl), библиотека будет автоматически пытаться повторно использовать существующие подключения, где это возможно - до тех пор, пока вы повторно используете ту же простую ручку.

Если да, то как мало мы можем получить запрос?

Предполагается, что на вашем сервере используется конечная точка ping, которая не принимает данные и возвращает ответ 204 (успешно, но без содержимого)тогда накладные расходы на уровне приложения будут равны размеру заголовков HTTP-запроса + размеру заголовков HTTP-ответа.Возможно, вы могли бы уменьшить его до 200-300 байт или около того.

Альтернативы (простому) HTTP

Если вы используете RESTful API, эта парадигма противоречит идеепостоянное TCP-соединение - хотя я не могу придумать причину, по которой оно не будет работать.

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

По сравнению с обычным HTTP веб-сокеты предлагают:

  • значительно меньше накладных расходов, чем HTTP на сообщение;
  • соединение автоматически сохраняется: нет необходимости отправлять дополнительные сообщения «keep alive», чтобы держать его открытым;

По сравнению с необработанным TCP-соединением, преимущества веб-сокетов заключаются в следующем:

  • вам не нужно открывать пользовательский порт на вашем сервере;
  • он автоматически обрабатывает TLS / SSL для вас.

(Кто-токто знает больше о веб-сокетах, может поправить меня в некоторых из вышеперечисленных моментов, особенно в отношении TLS / SSL и поддержки сообщений.)

Альтернативы libcurl

Альтернатива libcurl, которая может бытьполезной здесь является сетевая библиотека Mongoose .Это предоставит вам несколько различных альтернатив:

  1. использовать простое TCP-соединение (и собственный протокол прикладного уровня),
  2. использовать TCP-соединение и обрабатывать HTTP-запросы самостоятельно
  3. использовать веб-сокеты - которые он очень хорошо поддерживает (как сервер, так и клиент).

Mongoose также позволяет включать SSL для всех этих параметров.

...