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

Easy way to "nudge" a server to keep a connection open?

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

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

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

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

我的印象是 "TCP keep-alive" 数据包存在的原因,但据推测那些 "check the connection" 不像名字所暗示的那样 "keep it open"。

我的想法是这样的:

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

我的问题是:

  1. 这有意义吗?
  2. 我想在 libcurl 中没有简单的方法可以做到这一点吗?
  3. 如果是这样,我们能得到多小的请求?
  4. 有更简单的方法吗?我这里唯一的问题是 libcurl.
  5. 中的所有连接内容 "lives"

谢谢!

如果您提供有关您的应用程序架构的更多详细信息,则更容易给出更准确的答案。例如,它是RESTfulAPI吗?使用 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 的 application-layer 概念 - 无论是否在传输层使用 keep-alive 数据包都可以使用。

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

使用 libcurl 的问题在于它首先是一个 transfer 库。我不认为它是为 long-running、持久的 TCP 连接量身定做的。尽管如此,根据 Daniel Stenberg(libcurl 的作者)的说法,库 will automatically try to reuse existing connections where possible - 只要您 re-use 同样容易处理。

If so, how small could we get the request?

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

(普通)HTTP 的替代方案

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

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

与普通 HTTP 相比,websockets 提供:

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

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

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

(欢迎了解更多关于 websockets 的人在上述一些问题上纠正我 - 特别是关于 TLS/SSL 和 keep alive 消息。)

libcurl 的替代品

Mongoose networking library 可能在这里有用的 libcurl 的替代方法。它将为您提供几个不同的选择:

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

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