HTTP/2 协议协商的当前形式:
HTTP/2 连接以以下三种方式之一启动:
-
在使用 ALPN(应用层协议协商)的加密连接 (TLS/SSL) 中。大多数浏览器要求 HTTP/2 使用 TLS/SSL,并使用此方法建立 HTTP/2 连接。
-
以明文形式,使用 HTTP/1.1Upgrade
标头(与 Websocket 相同)。大多数浏览器都需要 HTTP/2 的 TLS/SSL,因此其支持受到限制。
-
以明文形式,在 HTTP/1.1 连接的开头使用特殊字符串(这可以允许明文形式的 HTTP/2 服务器禁用 HTTP/1.1 支持)。有限的客户支持。
协商 Websocket 协议,现在时:
目前,协商 Websocket 连接需要 HTTP/1.1 支持并利用 HTTP/1.1Upgrade
header.
这通常由侦听 HTTP/1.1 和 HTTP/2 连接的同一应用程序服务器执行。支持并发(无论是基于事件还是基于线程)的 Web 应用程序通常与协议无关(只要保留 HTTP 语义)并且在这两种协议上都能很好地工作。
这允许在连接建立期间使用 HTTP 数据(并且可能影响 Websocket 连接状态/身份验证过程)。
Websocket 连接一旦建立,就完全独立于 HTTP 语义/层。
在 HTTP/2 世界中协商 Websocket 协议:
在未来一段时间(仅 HTTP/2)的世界中,可能有多种可能的 Websocket 协议协商方法:基于 ALPN 的方法和 HTTP/2“隧道”(或“流”)方法。
ALPN 方法以牺牲预升级 (HTTP) 阶段为代价来保留协议独立性,而“流”方法则提供 HTTP 预“升级”(或Connect
)阶段的代价是高耦合性和复杂性。
ALPN 方法:
未来一种可能的方法是简单地将 Websocket 协议添加到ALPN谈判 https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids table.
目前,ALPN 用于选择(或默认)“http/1.1”协议和Upgrade
请求由 HTTP/1.1 服务器处理。这意味着Websocket在协议协商期间仍然为我们提供HTTP头数据(同时使用它自己的TCP/IP连接)
将来,ALPN 可能会简单地添加“wss”作为可用选项。
使用这种方法,Websocket(目前使用 HTTP/1.1 建立)Upgrade
可以使用 TLS/SSL 层的 ALPN 扩展轻松协商(无论是加密文本形式还是明文形式)。
这将使 Websocket 协议独立于 HTTP/2 协议,并且即使在不支持 HTTP 时也允许使用它。
然而,这会带来一个缺点,即 cookie 和其他 HTTP 标头可能不再作为协议协商的一部分可用。另一个区别(有好有坏)是这种方法需要单独的 TCP/IP 连接。
HTTP/2“隧道”/“流”方法
另一种未来可能的方法,反映了在这份拟议草案中 https://datatracker.ietf.org/doc/html/draft-mcmanus-httpbis-h2-websockets-00.html,将处理 Websocket 协议的 HTTP/1.1 变体,转而采用 HTTP/2“流”方法。
HTTP/2“流”是 HTTP/2 实现多路复用并允许同时处理多个请求的方式。每个请求都会接收一个流编号 ID,并且与该请求相关的任何数据(标头、响应等)均使用相同的数字流 ID 来标识。
在这种方法下,“Websocket”数据将包含在 HTTP/2 包装器中,并且流 ID 将用于标识“Websocket”流。
尽管这可能会带来一些好处(HTTP 标头和 cookie 可以作为 Websocket 协商的一部分提供),但它也并非没有缺点。
更高的复杂性和更紧密的协议耦合只是两个例子,两者都是非常严重的缺陷。
结论:
在撰写本文时,HTTP/1.1Upgrade
Websocket 连接需要语义,无论是使用明文(ws
)和加密的(wss
)连接。
到目前为止,未来尚未确定,当前的升级过程(使用 HTTP/1.1)可能需要很长时间才能被淘汰