HTTP/2 世界中的 WebSockets 替代方案是什么?
What is the WebSockets alternative in the HTTP/2 world?
新的 HTTP/2 协议具有一些很有前途的功能。其中一些:
- 多路复用 - 单个 TCP 连接可用于发出多个 HTTP/2 请求并接收多个响应(对单个来源)
- HTTP/2 Server Push - 向客户端发送服务器响应而不接收请求,即由服务器发起
- 双向连接 - HTTP/2 spec - Streams and Multiplexing:
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 连接以三种方式之一开始:
在使用 ALPN(应用层协议协商)的加密连接 (TLS/SSL) 中。大多数浏览器要求 TLS/SSL 用于 HTTP/2 并使用此方法建立 HTTP/2 连接。
在明文中,使用 HTTP/1.1 Upgrade
header(与 Websockets 相同)。大多数浏览器需要 TLS/SSL 来代替 HTTP/2,因此它的支持有限。
在明文中,在 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)
新的 HTTP/2 协议具有一些很有前途的功能。其中一些:
- 多路复用 - 单个 TCP 连接可用于发出多个 HTTP/2 请求并接收多个响应(对单个来源)
- HTTP/2 Server Push - 向客户端发送服务器响应而不接收请求,即由服务器发起
- 双向连接 - HTTP/2 spec - Streams and Multiplexing:
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
现在的问题是:如果我们希望 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 连接以三种方式之一开始:
在使用 ALPN(应用层协议协商)的加密连接 (TLS/SSL) 中。大多数浏览器要求 TLS/SSL 用于 HTTP/2 并使用此方法建立 HTTP/2 连接。
在明文中,使用 HTTP/1.1
Upgrade
header(与 Websockets 相同)。大多数浏览器需要 TLS/SSL 来代替 HTTP/2,因此它的支持有限。在明文中,在 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)