【问题标题】:Easy way to "nudge" a server to keep a connection open?“轻推”服务器以保持连接打开的简单方法?
【发布时间】:2019-10-16 12:55:24
【问题描述】:

好的,这里有一点上下文: 我有一个在嵌入式系统上运行的应用程序,它按以下时间间隔通过 HTTP(在 C++ 中使用 libcurl)发送几个不同的请求: 5分钟 15分钟 1小时 24小时

我的目标:减少数据消耗(通过蜂窝网络运行)

我们同时拥有客户端和服务器端的 TLS 身份验证,因此握手成本很高。我们的想法是我们使用持久连接(至少对于较短间隔的文件)来避免每次都进行握手。

不幸的是,经过多次修改后,我发现服务器在间隔过去之前关闭了连接。也许这是我们可以扩展的东西?我得和服务器端的人谈谈。

我的印象是“TCP keep-alive”数据包存在的原因,但据说那些“检查连接”而不是“保持打开”,就像名字所暗示的那样。

我的想法是这样的:

让我的应用每 2 分钟左右(不管超时有多长)发送一个数据包(尽可能小),以“推动”连接保持打开状态。

我的问题是:

  1. 这有意义吗?
  2. 我认为在 libcurl 中没有简单的方法可以做到这一点吗?
  3. 如果是这样,我们可以得到多小的请求?
  4. 有更简单的方法吗?我唯一的问题是所有连接的东西都“存在”在 libcurl 中。

谢谢!

【问题讨论】:

  • 请注意,您为使连接保持打开状态所做的任何事情都会增加带宽成本,可能会大大增加。
  • 是的,我已经考虑过了。计划是实施这样的事情并进行一些测试以比较数字。可能只需要为较短的上传间隔实现它。如果可能的话,还希望将我发送的任何内容减少到 50 字节以下。
  • 能否加密数据并切换到 HTTP / 删除 TLS 身份验证步骤? (可能在建立初始 TLS 连接以首先交换一些密钥之后。)

标签: c++ http libcurl keep-alive


【解决方案1】:

如果您提供有关您的应用程序架构的更多细节,则更容易给出更准确的答案。例如,它是 RESTful API 吗?使用 HTTP 是绝对必要的吗?如果是这样,您使用的是什么 HTTP 服务器(nginx、apache、...)?你可以考虑将 websockets 作为普通 HTTP 的替代品吗?

如果您可以随意使用常规 HTTP 或 HTTPS 以外的东西 - 并在客户端使用 libcurl 以外的东西 - 您会有更多选择。

如果,另一方面,如果你被限制在两个方面

  1. 使用 HTTP(而不是原始 TCP 连接或 websocket),并且
  2. 使用 libcurl

那么我认为你的任务更难一些 - 但也许仍然有可能。

您面临的首要挑战之一是 HTTP 连接的典型超时非常低(对于 Apache 2 低至几秒)。如果你可以配置服务器,你可以增加这个。

我的印象是“TCP keep-alive”数据包存在的原因,但据说那些“检查连接”而不是“保持打开”,就像名字所暗示的那样。

您的术语在这里含糊不清。您是指 TCP 保持活动数据包还是持久 HTTP 连接?这些不一定彼此有任何关系。前者是 TCP 中的可选机制(默认禁用)。后者是一个特定于 HTTP 的应用层概念,无论是否在传输层使用 keep-alive 数据包,都可以使用后者。

我唯一的问题是所有连接的东西都“存在”在 libcurl 中。

使用 libcurl 的问题在于它首先是一个 transfer 库。我不认为它是为长时间运行的持久 TCP 连接量身定制的。尽管如此,根据 Daniel Stenberg(libcurl 的作者)的说法,库 will automatically try to reuse existing connections where possible - 只要您重复使用相同的简单句柄。

如果是这样,我们可以得到多小的请求?

假设您在服务器上使用“ping”端点——它不接受数据并返回 204(成功但没有内容)响应,那么开销——在应用层——将是 HTTP 请求标头的大小+ HTTP 响应标头的大小。也许你可以把它减少到 200-300 字节左右。

(纯)HTTP 的替代方案

如果您使用的是 RESTful API,那么这种范式有点违背持久 TCP 连接的想法——尽管我想不出它为什么不起作用的任何原因。

您可能会考虑将 websockets 作为替代方案,但是 - 再一次 - libcurl 并不适合此。虽然我对 websocket 知之甚少,但我相信它们会提供一些优势。

与普通 HTTP 相比,websockets 提供:

  • 每条消息的开销明显低于 HTTP;
  • 连接会自动保持:无需发送额外的“保持活动”消息来保持打开状态;

与原始 TCP 连接相比,websocket 的好处在于:

  • 您不必在服务器上打开自定义端口;
  • 它会自动为您处理 TLS/SSL 内容。

(欢迎对 websockets 有更多了解的人就以上几点纠正我 - 特别是关于 TLS/SSL 和保持活动消息。)

libcurl 的替代品

libcurl 的替代品在这里可能有用的是Mongoose networking library。它会为您提供一些不同的选择:

  1. 使用纯 TCP 连接(和自定义应用层协议),
  2. 使用 TCP 连接并自己手动处理 HTTP 请求,
  3. 使用 websockets - 它对它有很好的支持(作为服务器和客户端)。

Mongoose 还允许您为所有这些选项启用 SSL。

【讨论】:

  • 嗨!感谢您的回复。这很有帮助。另外,抱歉有点模棱两可,我对所有这些东西都是新手。我研究得越多,我就越觉得我正在尝试用 HTTP 做一些你真的不应该做的事情(这几乎就是你所说的)。无论如何,经过一点阅读,看起来 websockets 可能是正确的道路(我仍然需要问我的老板)。谢谢你的提示!您对开源和/或免费用于商业用途的 C++ websockets 库有什么建议吗?我看到猫鼬不是。再次感谢!
  • @Hyperion:en.wikipedia.org/wiki/Comparison_of_WebSocket_implementations 的列表包括一些 C++ 库 - 例如Oat++ 和 websocketpp。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 2015-04-18
  • 2013-12-19
  • 2012-01-29
  • 1970-01-01
  • 2020-06-03
相关资源
最近更新 更多