HTTP/2 协议协商的当前形式:
HTTP/2 连接以以下三种方式之一开始:
-
在使用 ALPN(应用层协议协商)的加密连接 (TLS/SSL) 中。大多数浏览器都要求 HTTP/2 使用 TLS/SSL,并使用此方法建立 HTTP/2 连接。
-
以明文形式,使用 HTTP/1.1 Upgrade 标头(与 Websockets 相同)。大多数浏览器都要求对 HTTP/2 使用 TLS/SSL,因此对它的支持是有限的。
-
在明文中,在 HTTP/1.1 连接的开头使用特殊字符串(这可能允许明文中的 HTTP/2 服务器禁用 HTTP/1.1 支持)。有限的客户支持。
协商 Websocket 协议,现在时:
目前,协商 Websocket 连接需要 HTTP/1.1 支持并使用 HTTP/1.1 Upgrade 标头。
这通常由侦听 HTTP/1.1 和 HTTP/2 连接的同一应用程序服务器执行。支持并发(无论是基于事件的还是基于线程的)的 Web 应用程序通常与协议无关(只要保留 HTTP 语义),并且在两种协议上都运行良好。
这允许在连接建立期间使用 HTTP 数据(并可能影响 Websocket 连接状态/身份验证过程)。
一旦建立 Websocket 连接,它就完全独立于 HTTP 语义/层。
在 HTTP/2 世界中协商 Websocket 协议:
在一个 HTTP/2(仅)世界中,可能在未来一段时间内,可能有许多可能的 Websocket 协议协商方法:基于 ALPN 的方法和 HTTP/2“隧道”(或“流") 方法。
ALPN 方法以牺牲升级前 (HTTP) 阶段为代价来保留协议独立性,而“流”方法以牺牲高耦合和复杂性。
ALPN 方法:
未来一种可能的方法是将 Websocket 协议简单地添加到the ALPN negotiation 表中。
目前,ALPN 用于选择(或默认为)“http/1.1”协议,Upgrade 请求由 HTTP/1.1 服务器处理。这意味着 Websocket 在协议协商期间仍然为我们提供 HTTP 头数据(同时使用它自己的 TCP/IP 连接)
未来,ALPN 可能会简单地添加“wss”作为可用选项。
使用这种方法,可以使用 TLS/SSL 层的 ALPN 扩展轻松协商 Websocket(目前使用 HTTP/1.1 Upgrade 标头,以加密和明文形式建立)。
这将使 Websocket 协议独立于 HTTP/2 协议,即使在不支持 HTTP 的情况下也可以使用它。
但是,这将带来一个缺点,即 cookie 和其他 HTTP 标头可能不再作为协议协商的一部分可用。另一个区别(好的和坏的)是这种方法需要一个单独的 TCP/IP 连接。
HTTP/2“隧道”/“流”方法
in this proposed draft 反映的另一种未来可能的方法将弃用 Websocket 协议的 HTTP/1.1 变体,转而采用 HTTP/2“流”方法。
HTTP/2“流”是 HTTP/2 实现多路复用并允许同时处理多个请求的方式。每个请求都会收到一个流编号 ID,与此请求相关的任何数据(标头、响应等)都使用相同的数字流 ID 进行标识。
在这种方法下,“Websocket”数据将包含在 HTTP/2 包装器中,并且流 ID 将用于标识“Websocket”流。
虽然这可能会带来一些好处(HTTP 标头和 cookie 可以作为 Websocket 协商的一部分提供),但也并非没有缺点。
更高的复杂性和更紧密的协议耦合只是两个例子,两者都是非常严重的失败。
结论:
在撰写本文时,使用明文 (ws) 和加密 (wss) 连接时,Websocket 连接都需要 HTTP/1.1 Upgrade 语义。
未来尚未确定,目前的升级过程(使用 HTTP/1.1)可能需要很长时间才能逐步淘汰