HTTP/2 世界中的 WebSockets 替代方案是什么?

What is the WebSockets alternative in the HTTP/2 world?

新的 HTTP/2 协议具有一些很有前途的功能。其中一些:

A "stream" is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection.

HTTP/2 背后的动机解释如下 HTTP/2 FAQ

HTTP/1.1 has served the Web well for more than fifteen years, but its age is starting to show.

The goal of the Working Group is that typical uses of HTTP/1.x can use HTTP/2 and see some benefit.

所以 HTTP/2 很好,可以取代 HTTP/1.x。不幸的是,HTTP/2 does not support WebSockets. In this question it is made clear that the HTTP/2 Server Push is not an alternative, neither are Server-Sent Events.

现在的问题是:如果我们希望 WebSockts 功能优于 HTTP/2,我们应该使用什么?

您的一个链接实际上有一个答案:您可以只使用 SSE。

从语义上讲,您可以使用 websockets 或 (SSE + POST ) 实现相同的目的。粗略地说,这两种技术解决不同用例的观点是围绕 "this syntax works better for this" 进行自行车运动。

正在努力将类似于 websockets 的东西移植到 HTTP/2,但除非这些技术使新的用例或效率成为可能,否则我认为没有意义。

好吧,你的时机恰到好处!

新版互联网标准草案刚刚发布:

Bootstrapping WebSockets with HTTP/2

此处的附加信息:

https://github.com/mcmanus/draft-h2ws/blob/master/README.md

您可以在此处关注其中的讨论:

https://lists.w3.org/Archives/Public/ietf-http-wg/2017OctDec/0032.html

直到它被批准,然后由浏览器和服务器实现,我会说 Daniel Haxx’s post that you included in your question 代表了对当前状态的一个很好的总结。

HTTP/2协议协商的当前形式:

HTTP/2 连接以三种方式之一开始:

  1. 在使用 ALPN(应用层协议协商)的加密连接 (TLS/SSL) 中。大多数浏览器要求 TLS/SSL 用于 HTTP/2 并使用此方法建立 HTTP/2 连接。

  2. 在明文中,使用 HTTP/1.1 Upgrade header(与 Websockets 相同)。大多数浏览器需要 TLS/SSL 来代替 HTTP/2,因此它的支持有限。

  3. 在明文中,在 HTTP/1.1 连接的开头使用特殊字符串(这可能允许 HTTP/2 服务器在明文中禁用 HTTP/1.1 支持)。有限的客户支持。

协商 Websocket 协议,现在时:

协商 Websocket 连接,目前需要 HTTP/1.1 支持并使用 HTTP/1.1 Upgrade header.

这通常由侦听 HTTP/1.1 和 HTTP/2 连接的同一应用程序服务器执行。支持并发(无论是基于事件还是基于线程)的 Web 应用程序通常与协议无关(只要保留 HTTP 语义)并且在两种协议上都能很好地工作。

这允许在连接建立期间使用 HTTP 数据(并且可能影响 Websocket 连接 state/authentication 过程)。

一旦建立了 Websocket 连接,它就完全独立于 HTTP 语义/层。

在 HTTP/2 世界中协商 Websocket 协议:

在 HTTP/2(仅)的世界中,可能需要一段时间,Websocket 协议协商可能有多种可能的方法:基于 ALPN 的方法和 HTTP/2 “隧道”(或“流”)方法。

ALPN 方法以 pre-upgrade (HTTP) 阶段为代价保留协议独立性,而“流”方法提供 HTTP 预“升级”(或 Connect)阶段高耦合和复杂性的代价。

ALPN 方法:

一种可能的未来方法是将 Websocket 协议简单地添加到 the ALPN negotiation table.

目前,ALPN 用于 select(或默认)“http/1.1”协议,Upgrade 请求由 HTTP/1.1 服务器。这意味着 Websocket 在协议协商期间仍然为我们提供 HTTP header 数据(同时使用它自己的 TCP/IP 连接)

将来,ALPN 可能会简单地添加“wss”作为可用选项。

使用这种方法,可以很容易地使用ALPN 扩展到 TLS/SSL 层。

这将使 Websocket 协议独立于 HTTP/2 协议,即使在不支持 HTTP 的情况下也可以使用它。

然而,这会带来一个缺点,即 cookie 和其他 HTTP headers 可能不再作为协议协商的一部分可用。另一个区别(好的和坏的)是这种方法需要一个单独的 TCP/IP 连接。

HTTP/2“隧道”/“流”方法

反映 in this proposed draft 的另一种可能的未来方法将处理 Websocket 协议的 HTTP/1.1 变体,转而采用 HTTP/2“流”方法。

HTTP/2 “流”是 HTTP/2 实现多路复用并允许同时处理多个请求的方式。每个请求都会收到一个流编号 ID,并且与此请求相关的任何数据(headers、响应等)都使用相同的数字流 ID 进行标识。

在这种方法下,“Websocket”数据将包含在 HTTP/2 包装器中,流 ID 将用于识别“Websocket”流。

虽然这可能会提供一些好处(HTTP headers 和 cookie 可以作为 Websocket 协商的一部分提供),但它并非没有缺点。

更高的复杂性和更紧密的协议耦合只是两个例子,两者都是非常严重的失败。

结论:

在撰写本文时,HTTP/1.1 Websocket 连接需要 Upgrade 语义,无论是使用明文 (ws) 还是加密 (wss) 连接。

未来尚未确定,可能需要很长时间才能逐步淘汰当前升级过程(使用 HTTP/1.1)