HTTP/2 或 Websockets 用于低延迟客户端到服务器消息
Posted
技术标签:
【中文标题】HTTP/2 或 Websockets 用于低延迟客户端到服务器消息【英文标题】:HTTP/2 or Websockets for low latency client to server messages 【发布时间】:2018-11-30 02:11:09 【问题描述】:我的 Web 应用程序中要求客户端到服务器消息的延迟非常低。
我在 *** 上看到了几篇帖子,说最好使用 websockets 而不是 HTTP 来满足这个要求,但那是很久以前的事了。
在 2018 年的今天,随着 HTTP/2 的进步,这个用例还值得使用 websockets 吗?
【问题讨论】:
【参考方案1】:在我的 Web 应用程序中,客户端到服务器消息的延迟非常低。
我认为您想“连接”然后在 client 和 server 之间发送 低延迟消息。
HTTP/2 和 Websocket 都可以是二进制的,并且传输消息的帧具有相似的开销(几个字节),但 Websocket 必须遍历完整消息以屏蔽有效负载然后接收器必须将其反转。见What is the mask in a WebSocket frame?
此外,Websocket 原语更底层,例如要拥有多个消息流,您必须自己完成,但使用 HTTP/2 很容易完成。参考Podcast about HTTP/2。在同一个应用程序中同时使用 Websocket 和 HTTP 时,服务器代码也会变得更加复杂。
流控制在使用 HTTP/1.1 Websocket 时可能会出现问题,但它是 HTTP/2 中的内置协议功能。
服务器到客户端
这可以通过使用fetch
和response.body.getReader();
获得ReadableStream 来有效地使用HTTP/2 完成。一篇关于浏览器 javascript 流的好文章:2016 - the year of web streams。
客户端到服务器
目前,在 HTTP 中从客户端向服务器发送消息的唯一方法是发送 完整请求。流式请求正文已计划但尚未由浏览器实现。有关流式请求正文,请参阅 Fetch with ReadableStream as Request Body。
【讨论】:
【参考方案2】:HTTP/2 有multiplexing,这意味着不应该有等待时间——就像在 HTTP/1 下由于每个域有 6 个连接限制。所以这意味着它可以用于你所说的低延迟连接。
但是,HTTP 仍有其他开销,例如 HTTP 标头,这可能会为小型请求添加大量不必要的额外数据,而使用 Web 套接字则不会。
此外,HTTP/2 不是全双工协议,因此只能响应请求(尽管由于服务器推送,可能会有多个响应)。你说你只需要这个来进行客户端-服务器消息传递,所以这对你来说可能不是那么重要。
支持 HTTP/2 的二进制框架层是一个全双工协议,因此理论上可能类似于 websockets,但 HTTP/2 不允许这样做 - 除非你只是拖出发送请求和响应主体来伪造它(@ 987654322@ 或 Server-Sent Events)。事实上,Websockets over HTTP/2 已获批准,通过在 HTTP/2 数据帧中包装 websockets 消息,将允许 HTTP/2 二进制格式用于 websockets。这还有一个额外的优势,即还允许在同一连接上发送常规 HTTP 消息。在撰写本文时,它还没有在任何浏览器中可用(尽管有 version 65 of FireFox 和 Chrome has started an implementation)。在那之前,Websockets 会恢复到 HTTP/1.1。
另请参阅此问题和答案:Does HTTP/2 make websockets obsolete?
【讨论】:
对“http 消息大小”部分的快速说明:是的,http2 带有 HPACK 用于智能标头压缩,它有助于将标头大小保持在合理的低水平。是的,http2 确实比 websocket(它也支持压缩)更好地遵循有效载荷压缩的压缩趋势。说了所有这些之后,请记住,http2 会为所有这些智能复杂性(CPU、RAM)以及如果你必须处理随机的 http 标头(比如跟踪频繁更改的 cookie 或 w/e ) 您将很难保持消息大小可预测且较小。只是我的 2c。【参考方案3】:这将取决于您的客户和您的要求。如果您确定您的客户端不会关闭 HTTP/2 的底层 TLS 连接(即使一段时间未使用),则发送消息/请求的延迟可能类似于持久的 websocket 连接。如果客户端在空闲一段时间后关闭连接,需要建立新的 TLS 连接,情况会更糟。
在浏览器作为客户端的情况下,您知道 Web 套接字连接将是持久的,并且对 HTTP 连接一无所知。也许您可以通过向同一服务器上的 SSE 端点发出虚拟请求并保持连接来强制浏览器保持连接,但这是一种解决方法。
除了建立连接外,两种协议都有不同类型的开销(流控制和流标头与掩码),并且很可能只能根据实际应用需求来估计影响。
【讨论】:
以上是关于HTTP/2 或 Websockets 用于低延迟客户端到服务器消息的主要内容,如果未能解决你的问题,请参考以下文章
HTTP/2 世界中的 WebSockets 替代方案是啥?
WebSockets 或 Http 哪一个用于实时应用程序?
Spring Batch:用于高容量和低延迟的 ItemReader 实现