【问题标题】:HTTP/2 or Websockets for low latency client to server messagesHTTP/2 或 Websockets 用于低延迟客户端到服务器消息
【发布时间】:2018-11-30 02:11:09
【问题描述】:

我的 Web 应用程序中要求客户端到服务器消息的延迟非常低。

我在 stackoverflow 上看到了几篇帖子,说最好使用 websockets 而不是 HTTP 来满足这个要求,但那是很久以前的事了。

在 2018 年的今天,随着 HTTP/2 的进步,这个用例还值得使用 websockets 吗?

【问题讨论】:

    标签: websocket http2


    【解决方案1】:

    在我的 Web 应用程序中,客户端到服务器消息的延迟非常低。

    我认为您想“连接”然后在 clientserver 之间发送 低延迟消息

    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 中的内置协议功能。

    服务器到客户端

    这可以通过使用fetchresponse.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 FireFoxChrome 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 端点发出虚拟请求并保持连接来强制浏览器保持连接,但这是一种解决方法。

      除了建立连接外,两种协议都有不同类型的开销(流控制和流标头与掩码),并且很可能只能根据实际应用需求来估计影响。

      【讨论】:

        猜你喜欢
        • 2016-11-12
        • 1970-01-01
        • 2020-09-06
        • 2018-03-17
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 2012-12-05
        • 2013-08-17
        相关资源
        最近更新 更多