我正在学习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

其他回答

根据我的理解,HTTP/2不是websocket的替代品,而是旨在标准化SPDY协议。

在HTTP/2中,服务器推送(server-push)在后台使用,以改善客户端从浏览器加载资源的情况。作为一名开发人员,你在开发过程中并不会真正关心它。然而,使用Websocket,开发者可以使用API,它可以使用唯一的全双工连接来消费和推送消息。

这些不是一回事,它们应该是相辅相成的。

消息交换和简单的流(不是音频,视频流)可以通过Http/2多路复用和WebSockets来完成。所以有一些重叠,但是WebSockets有很好的协议,很多框架/ api和更少的头开销。 这里有一篇关于这个主题的好文章。

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

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

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

引用InfoQ的一篇文章:

好吧,答案显然是否定的,原因很简单:正如我们上面所看到的,HTTP/2引入了Server Push,它使服务器能够主动地向客户端缓存发送资源。但是,它不允许将数据下推到客户机应用程序本身。服务器推送仅由浏览器处理,不会弹出到应用程序代码中,这意味着应用程序没有API来获取这些事件的通知。

所以HTTP2推送实际上是浏览器和服务器之间的东西,而Websockets实际上公开了可以被客户端(javascript,如果它运行在浏览器上)和应用程序代码(运行在服务器上)使用的api来传输实时数据。

我说不(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容器的行为方式。