如何保持 HTTP 长轮询连接打开?

How to keep a HTTP long-polling connection open?

本文关键字:连接 何保持 HTTP      更新时间:2023-10-16

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

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

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

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

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

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

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

其中一种设计如下:

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

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