c++ - "nudge"服务器保持连接打开的简单方法?

标签 c++ http libcurl keep-alive

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

我的目标:减少数据消耗(通过手机运行)

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

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

我的印象是这就是“TCP 保持事件”数据包存在的原因,但据推测那些“检查连接”而不是像名称所暗示的那样“保持打开”。

我的想法是这样的:

让我的应用程序每 2 分钟左右(无论超时有多长)发送一个数据包(尽可能小)以“插入”连接保持打开状态。

我的问题是:

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

谢谢!

最佳答案

如果您提供有关应用程序架构的更多详细信息,则更容易给出更准确的答案。例如,它是 RESTful API 吗?使用 HTTP 是绝对强制性的吗?如果是这样,您使用的是什么 HTTP 服务器(nginx、apache 等)?您能否考虑将 websockets 作为普通 HTTP 的替代品?

如果您可以自由地使用常规 HTTP 或 HTTPs 以外的东西 - 并且在客户端使用 libcurl 以外的东西 - 您会有更多选择。

如果,另一方面,如果你对两者都有限制

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

然后我认为你的任务有点困难 - 但也许仍有可能。

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

I was under the impression that was the reason the "TCP keep-alive" packets existed, but supposedly those "check the connection" not "keep it open" like the name suggests.

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

My only issue here is that all the connection stuff "lives" in libcurl.

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

If so, how small could we get the request?

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

(普通)HTTP 的替代方案

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

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

与普通 HTTP 相比,websockets 提供:

  • 每条消息的开销明显低于 HTTP;
  • 连接自动持续:无需发送额外的“保持事件”消息来保持连接;

与原始 TCP 连接相比,websockets 的优势在于:

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

(欢迎了解更多关于 websockets 的人就上述一些要点纠正我 - 特别是关于 TLS/SSL 和保持事件消息。)

libcurl 的替代品

这里可能有用的 libcurl 替代方法是 Mongoose networking library .它会为您提供几种不同的选择:

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

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

关于c++ - "nudge"服务器保持连接打开的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56385513/

相关文章:

c++ - 如何将一个简单的 QSqlQueryModel 从一个类返回到另一个类?

java - java中的等效 cURL --data-binary @filename -H "Content-Type:text/csv"

java - WildFly 8.2 和 304 未修改

http - ISO-8859-1 编码网站中的变音符号

c++ - libcurl 中是否有可用的压缩

c++ - 在 C++ 中使用默认构造函数

c++ - wxWidgets 绘制实时图形的最佳控件

c++ - 立即退出 C++ 应用程序?

c++ - 如何获取页面的 "full source"?

git - 如何强制 Git(2.5+)HTTP 传输更喜欢 SPNEGO 而不是基本身份验证?