【问题标题】:How to keep a HTTP long-polling connection open?如何保持 HTTP 长轮询连接打开?
【发布时间】:2017-08-15 17:35:22
【问题描述】:

我想在 Web 服务中实现长轮询。我可以在客户端上设置足够长的超时时间。 我能否提示中间网络组件以保持响应 开放?我的意思是 NAT、病毒扫描程序、反向代理或可能位于客户端之间的周围 SSH 隧道而服务器和我都不受我的控制。

下载可能会持续数小时,但空闲连接可能会在不到一分钟的时间内终止。这是我要防止的。我可以通知中间网络我在这里想要一个空闲连接,而不是因为服务器已断开连接吗?

如果是这样,怎么做?我已经搜索了大约四个小时,但没有找到这方面的信息。

  • 我应该发送200 OK,也许是一些标题,然后什么都没有?
  • 我必须回复102 Processing 而不是200 OK,然后一切都很好吗?
  • 我应该不时发送0x16(同步空闲)字节吗?如果是这样,在初始 HTTP 状态代码之前还是之后,在标头之前还是之后?他们是否将其放入传输的文件中,并且可能会破坏它?

Web 服务/服务器使用 Boost 使用 C++ 编写,返回的内容文件使用 Turtle 语法。

【问题讨论】:

  • 也许是HTTP persistent connection?如果您只是阅读 HTTP 1.1 规范,那么该选项应该已经很清楚了。
  • 我的意思是保持响应打开。 (我相应地更新了我的问题。)我认为长时间的下载可能会持续几个小时,而没有响应可能会在不到一分钟后导致超时。例如,PuTTY 有一些 TCP keep-alive 选项。我想知道 HTTP 是否也可以实现类似的功能。
  • @Someprogrammerdude 这并不能保证连接 和响应 将保持打开状态。这就是实现长轮询的库必须能够在长时间超时后重新连接的原因。
  • @Paramaeleon 获得长轮询权不容易。在服务器端尤其困难,糟糕的实现会耗费大量资源。你为什么不为此使用图书馆?为什么不使用一些 other 技术,例如 WebSockets 或永久帧?
  • 当然,重新连接是必须的。我想知道是否可以通过让中间网络知道服务器端尚未离线来保持所需的重新连接很少。

标签: c++ network-programming long-polling


【解决方案1】:

您不能强制代理延长其空闲超时时间,至少在没有管理权限的情况下不能。

好消息是,您可以设计长轮询解决方案,使其可以从突然关闭的连接中恢复。

这样的设计如下:

  1. 由于长轮询通常用于事件通知(想想观察者模式),因此您将序列号与每个事件相关联。
  2. 客户端发出一个 GET 请求,其中携带它所看到的最后一个事件的序列号,作为 URL 的一部分或在 cookie 中。
  3. 服务器维护最近事件的缓冲区。在接收到来自客户端的 GET 请求后,它会根据它们的序列号和客户端提供的序列号检查是否需要将任何缓冲事件发送到客户端。如果是这样,所有此类事件都将在一个 HTTP 响应中发送。响应在该点完成,以防有代理想要在进一步转发之前缓冲整个响应。
  4. 如果客户端是最新的,也就是说它没有错过任何缓冲的事件,服务器将延迟其响应,直到生成另一个事件。发生这种情况时,它会作为一个完整的 HTTP 响应发送。
  5. 当客户端收到响应时,它会立即发送一个新的。当它检测到连接已关闭时,它会创建一个新连接并发出新请求。

当使用 cookie 来传达客户端看到的最后一个事件的序列号时,客户端的实现变得非常简单。本质上,您只需在客户端启用 cookie 即可。

【讨论】:

  • 你描述的是正确的,这是我已经计划做的。我知道我不能在某些代理中欺骗硬超时。但是,例如,PuTTY 有一些 TCP keep-alive 选项。我想知道 HTTP 是否也可以实现类似的功能——“伪造正在运行的下载”。它可能仍会达到某个最大传输超时,但它应该可以避免无数据超时。
  • @Paramaeleon TCP keep-alive 在这种情况下并不是非常有用,因为a) 你无法控制它的间隔,b) 这不是关于延长连接,而是关于检测一种情况您的同伴在没有通知您的情况下死亡(重新启动)。虽然可以通过随时间发送小的无操作响应块来延长 HTTP 连接,但这种技巧在存在代理的情况下并不可靠。
  • @Paramaeleon 实际上,延长连接的另一种方法是限制延迟响应的时间。当达到该限制时,您发出一个空响应,客户端提交一个新响应。尽管如此,代理的超时时间总是有可能被设置为更小的值。最后,当您的系统能够抵抗突然关闭时,我看不出尝试延长连接的意义。
猜你喜欢
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2012-12-21
  • 2012-03-25
  • 2018-01-13
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
相关资源
最近更新 更多