我正在学习HTTP/2协议。它是一种带有小消息帧的二进制协议。它允许在单个TCP连接上进行流多路复用。从概念上看,它与WebSockets非常相似。

有没有计划淘汰websockets,代之以某种无头HTTP/2请求和服务器发起的推送消息?或者WebSockets将补充HTTP/2?


当前回答

答案是否定的。两者之间的目标是非常不同的。甚至有一个基于HTTP/2的WebSocket的RFC,它允许你在一个单一的HTTP/2 TCP管道上建立多个WebSocket连接。

通过减少打开新连接的时间,允许更多的通信通道,而不增加更多套接字、软irq和缓冲区的开销,HTTP/2上的WS将是一个资源节约的游戏。

https://datatracker.ietf.org/doc/html/draft-hirano-httpbis-websocket-over-http2-01

其他回答

到2020年4月为止,HTTP/2还没有淘汰WebSockets。WebSockets相对于HTTP2的最大优势是

HTTP/2 works only on Browser Level not Application Level

意味着HTTP/2不提供任何像WebSockets那样的JS API来允许通信和直接从应用程序(例如网站)向服务器传输某种JSON或其他数据。所以,就我所相信的,只有当HTTP/2开始提供类似WebSockets的API来与服务器通信时,WebSockets才会被淘汰。在此之前,它只是更新和更快的HTTP 1.1版本。

不,WebSockets并没有过时。然而,HTTP/2打破了为HTTP/1.1定义的websocket(主要是通过禁止使用Upgrade报头进行协议更新)。这就是为什么这个rfc:

https://datatracker.ietf.org/doc/html/rfc8441

定义了HTTP/2的websocket引导过程。

答案是否定的。两者之间的目标是非常不同的。甚至有一个基于HTTP/2的WebSocket的RFC,它允许你在一个单一的HTTP/2 TCP管道上建立多个WebSocket连接。

通过减少打开新连接的时间,允许更多的通信通道,而不增加更多套接字、软irq和缓冲区的开销,HTTP/2上的WS将是一个资源节约的游戏。

https://datatracker.ietf.org/doc/html/draft-hirano-httpbis-websocket-over-http2-01

没有HTTP/2并不会使websockets过时,但是通过HTTP/2的SSE提供了一个可行的替代方案。需要注意的是SSE不支持从服务器到客户端的未经请求的事件(HTTP/2也不支持):即客户端必须通过创建指定事件源端点的EventSource实例显式订阅。因此,您可能不得不稍微重新组织客户端如何安排事件的交付——我想不出有什么场景会出现这种技术障碍。

SSE works with HTTP/1.1. But HTTP/2 makes using SSE generally viable and competitive with websockets in terms of efficiency, instead of practically unusable in the case of HTTP/1.1. Firstly, HTTP/2 multiplexes many event source connections (or rather "streams" in HTTP/2 terms) onto a single TCP connection where as in HTTP/1.1 you'd need one connection for each. According to the HTTP/2 spec, millions of streams can be created per connection by default with the recommended (configurable) minimum being 100, where as browsers maybe severly limited in the number of TCP connections they can make. Second reason is efficiency: many streams in HTTP/2 is requires much less overhead than the many connections required in HTTP/1.1.

最后一件事是,如果你想用SSE取代websockets,你就放弃了一些构建在websockets之上的工具/中间件。我特别想的是套接字。io(这是很多人实际使用websockets的方式),但我相信还有很多。

我说不(Websockets并没有过时)。

第一个也是最常被忽视的问题是HTTP/2推送是不可执行的,可能会被代理、路由器、其他中介甚至浏览器忽略。

即(来自HTTP2草案):

中介可以接收来自服务器的推送,并选择不将它们转发到客户端。换句话说,如何利用推送的信息取决于中介。同样,中介可能选择向客户端进行额外的推送,而不需要服务器采取任何操作。

因此,HTTP/2 Push不能取代WebSockets。

此外,HTTP/2连接也会在一段时间后关闭。

的确,该标准规定:

HTTP/2连接是持久的。为了获得最佳性能,预期客户端不会关闭连接,直到确定不需要与服务器进行进一步的通信(例如,当用户导航离开特定的网页时)或直到服务器关闭连接。

但是…

鼓励服务器尽可能长时间地保持打开的连接,但允许在必要时终止空闲连接。当任何一个端点选择关闭传输层TCP连接时,终止端点应该首先发送一个超时帧(章节6.8),以便两个端点可以可靠地确定之前发送的帧是否已经处理,并优雅地完成或终止任何必要的剩余任务。

即使相同的连接允许在打开时推送内容,即使HTTP/2解决了HTTP/1.1的“keep-alive”引入的一些性能问题……HTTP/2连接不会无限期地保持打开状态。

网页也不能在关闭后重新启动HTTP/2连接(除非我们又回到了长时间拖拉的状态)。

EDIT(2017,两年后)

HTTP/2的实现表明,多个浏览器选项卡/窗口共享一个HTTP/2连接,这意味着push永远不会知道它属于哪个选项卡/窗口,从而消除了使用push替代Websockets的情况。

编辑(2020)

我不知道为什么人们开始对答案投反对票。如果说有什么不同的话,那就是从最初的答案发布到现在的几年证明了HTTP/2不能取代WebSockets,而且它的设计初衷也不是这样的。

当然,HTTP/2可能被用于隧道WebSocket连接,但这些隧道连接仍然需要WebSocket协议,它们将影响HTTP/2容器的行为方式。