HTTP2上的websockets也会在流中多路复用吗?



我正在尝试澄清/理解websockets是否也会使用流通过TCP连接进行多路复用HTTP/2。RFC8441的第5节似乎暗示了这一点

成功处理开场握手后,对等方应使用 CONNECT 事务中的 HTTP/2 流继续使用 WebSocket 协议 [RFC6455],就好像它是 [RFC6455] 中提到的 TCP 连接一样。 此时 WebSocket 连接的状态为 OPEN,如 [RFC6455] 第 4.1 节所定义。

HTTP/2 流闭包也类似于 [RFC6455] 的 TCP 连接闭包。 有序的 TCP 级闭包表示为END_STREAM标志([RFC7540],第 6.1 节(。 RST 异常用带有 CANCEL 错误代码的RST_STREAM帧([RFC7540],第 6.4 节(表示([RFC7540],第 7 节(。

但我的困惑源于这样一个事实,即即使使用 HTTP/1.1,虽然浏览器中的选项卡共享到同一主机的底层 TCP 连接(例如 chrome 建立 6 个 TCP 连接(,但在不同的选项卡中创建对同一主机的websocket会导致每个选项卡中不同的 TCP 连接。

我不确定为什么两者之间的差异以及websockets是否也可能是相同的HTTP/2

这里有任何专家可以澄清。谢谢。

但我的

困惑源于这样一个事实,即即使使用 HTTP/1.1,虽然浏览器中的选项卡共享到同一主机的底层 TCP 连接(例如 chrome 建立 6 个 TCP 连接(,但在不同的选项卡中创建到同一主机的 websocket 会导致每个选项卡中都有不同的 TCP 连接。

你是对的,不幸的是,这是HTTP/1.1的当前状况。

正如您所指出的,RFC 8441 已被指定用于解决此问题并通过 HTTP/2 流捎带 WebSocket"连接",因此可以只打开一个到源服务器的 TCP 连接,并将该连接用于 HTTP/2 通信和 WebSocket 通信。

HTTP/1.1 和 HTTP/2 之间的区别源于这样一个事实,即 HTTP/1.1 WebSocket 连接不能(有效地(池化。 每个 WebSocket 连接都绑定到一个特定的 URI(例如ws://host/path1(,应用程序更典型的是为不同的 URI 打开不同的 WebSocket 连接(而不是为同一 URI 打开许多 WebSocket 连接(。 因为它们不能池化,所以浏览器基本上必须允许无限数量的它们,每次从 JavaScript 调用new WebSocket(...)时都会有一个新的。

相反,使用 HTTP/2,您将能够在同一 HTTP/2 连接中打开新的 HTTP/2。 并发流的数量取决于浏览器实现,但通常约为 100 个(如果不是更多的话(,这为 HTTP/2 和 WebSocket 留下了大量的并发性(除非客户端应用程序确实滥用 WebSocket(。

幸运的是,无需更改客户端应用程序即可利用此功能。 当浏览器和服务器支持它时,您的应用程序将使用更少的资源(只有一个 TCP 连接(,而不是现在使用的许多资源。

[免责声明,我是 Jetty 中此类功能的实现者]

我们已经看到一些浏览器实现了此功能,我们正在 Jetty 10.0.x 服务器中完成此功能的实现,请参阅 https://github.com/eclipse/jetty.project/issues/3537。

在不同的

选项卡中创建到同一主机的websocket会导致每个选项卡中出现不同的TCP连接

WebSocket 连接始终是新的 TCP 连接,因为它必须执行升级到 WebSocket 连接的 HTTP/S 请求,因此如果成功,则不再是 HTTP/S 连接。 WebSocket 连接是不同的,不能共享或重用,这与 HTTP/S 连接不同(假设使用保持活动状态(。

最新更新