关于 http/2 的文章中关于双向和全双工的混淆

confusion regarding bidirectional and full-duplex in articles about http/2

一些描述 http/2 的文章称赞它既是双向的又是全双工的。

AFAIK 双向意味着通信是双向的,所以双工本质上是双向的,是吗?

双工可以由一个在某些特定点反转的单工流创建(半双工),也可以创建为两个相反的单工流(全双工)。

也许双向是关于如何发起消息交换?在http/1 中只有客户端可以通过向服务器发送请求发起,其中服务器returns 响应。在 http/2 中,服务器可以发送(推送)一些资源而无需明确要求。但是我们可以在http/1.1中使用Server-sent events(也就是在客户端和服务端稍微配置一下,服务端就可以推送消息了,但是还是结束了[=25= .1 协议).

当您考虑它时,您可能会注意到 http/1 也是双向和全双工的(因为流水线在半双工中是不可能的)。所以从 http/2 的角度来看这里没有变化。

发生变化的是 http/1 要求回复按照请求的准确顺序到达。 http/2 通过流和多路复用提升了这一点。

双向意味着您可以双向发送数据。

全双工意味着你可以同时向两个方向发送数据 - 你可以有两个线程,一个写入数据,一个读取数据,并发执行。

如果我们把"client"和"server"作为端点(不管两者之间有多少个TCP连接),那么显然HTTP/1.1和HTTP/2都是全双工。

如果我们将客户端和服务器之间的单个 TCP 连接的两端作为端点,那么 HTTP/1.1 和 HTTP/2 通常都是全双工的。

这对于 HTTP/2 来说很明显,但对于 HTTP/1.1 却鲜为人知,因为它通常被认为是 "first the request, then the response" 协议 - 然而,事实并非如此。这是完全可能的,例如,对于回显客户端发送的内容字节的服务器,让客户端进行大量上传,并且当上传仍在进行时,服务器已经开始响应回显字节 - 上传和下载同时进行。

我们现在可以输入从服务器到客户端的未经请求的通信问题。

这在 HTTP/1.1 中是不可能的。 即使使用服务器发送事件 (SSE),客户端发出请求并且服务器以 [​​=47=] 响应 - 但客户端必须首先发出请求。

在HTTP/1.1 中,从单个TCP 连接的角度来看,SSE 不是全双工的:客户端首先发出请求,然后服务器以"infinite response" 响应。从那时起,客户端只能通过另一个请求与服务器通信,这意味着打开一个新连接。

在 HTTP/2 中,SSE 是全双工的,因为由于 HTTP/2 多路复用,客户端可以通过在同一 TCP 连接上发出另一个请求来与服务器通信。

SSE "infinite response" 可以看作是 "the server writes chunks of data that can be interpreted as pushed messages" 但 SSE 协议太简单了,不允许从服务器到客户端的通用消息(例如数据不能是二进制的)。您不会考虑在服务器将数据推送到客户端时断断续续的下载:)

Unsolicited 从服务器到客户端的通信在 HTTP/2 中也是不可能的,因为 HTTP/2 可以 "push" 资源到客户端,但仅在先前请求的上下文中。

例如,HTTP/2客户端与服务器建立了连接,但随后没有发送任何请求;在这种情况下,服务器将无法向客户端推送任何内容(甚至欢迎页面也不行),因为它需要先前的请求才能这样做。

这就是为什么 HTTP/2 不能完全替代 WebSocket 协议的原因,WebSocket 协议是唯一可用于从服务器到客户端进行完全未经请求的通信的 Web 协议。