HTTP/2协议的当前形式:
HTTP/2连接有三种方式:
通过使用ALPN(应用层协议协商)进行加密连接(TLS/SSL)。大多数浏览器需要TLS/SSL来进行HTTP/2连接建立,因此使用此方法。
使用HTTP/1.1 Upgrade
头(与Websockets相同)进行明文传输。大多数浏览器需要TLS/SSL来进行HTTP/2,因此受到支持的限制。
在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)阶段,而“流”方法则提供了HTTP预“升级”(或Connect
)阶段,但代价是高度耦合和复杂性。
基于ALPN的方法:
一个可能的未来方法将简单地将Websocket协议添加到ALPN协商表中。
目前,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 "tunnel" / "stream" 方法
另一种可能的未来方法,反映在
这个提案草案中,将放弃WebSocket协议的HTTP/1.1变体,采用HTTP/2 "stream"方法。
HTTP/2 "stream" 是HTTP/2实现多路复用的方式,允许多个请求同时处理。每个请求都会收到一个流号ID,该请求相关的任何数据(标头、响应等)都使用同一数字流ID进行标识。
根据这种方法,“WebSocket”数据将包含在HTTP/2封装中,并使用流ID来标识“WebSocket”流。
虽然这可能会提供一些好处(HTTP标头和cookie可以作为WebSocket协商的一部分提供),但也存在缺点。
更高的复杂性和更紧密的协议耦合只是其中两个例子,这两个问题都非常严重。
结论:
在撰写本文时,WebSocket连接需要使用HTTP/1.1
Upgrade
语义,无论是使用明文(
ws
) 还是加密(
wss
)连接。
未来仍未决定,目前的升级过程(使用HTTP/1.1)可能需要很长时间才能停用。