Search code examples
http2bidirectionalduplex

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


Some articles describing http/2 are praising it for being both bidirectional and full-duplex.

AFAIK bidirectional means that communication is in both directions so duplex is by its nature bidirectional, yes?

Duplex can be created by one simplex stream that is reversed at some specific points (half-duplex) or it can be created as two opposite simplex streams (full-duplex).

Maybe bidirectional is about how can initiate a message exchange? In http/1 only client can initiate by sending request to the server in which the server returns a response. In http/2 a server can send (push) some resource without being explicitly asked for it. But we can use Server-sent events in http/1.1 (that is server can push messages if it wants to after doing a little bit configuration on both the client and the server, but it's still over http/1.1 protocol).

When you think about it you may notice that http/1 is as well bidirectional and full-duplex (since pipelining wouldn't be possible in half-duplex). So no change here from http/2 perspective.

What has changed is that http/1 required responses to arrive in exact order in which they were requested. http/2 lifts that with streams and multiplexing.


Solution

  • Bidirectional means you can send data in both directions.

    Full duplex means you can send data in both directions at the same time - you can have two threads, one writing data and one reading data, executing concurrently.

    If we take as endpoints "client" and "server" (no matter how many TCP connections between the two), then obviously both HTTP/1.1 and HTTP/2 are full duplex.

    If we take as endpoints the two ends of a single TCP connection between client and server, again both HTTP/1.1 and HTTP/2 are - in general - full duplex.

    This is obvious for HTTP/2 but less known for HTTP/1.1 because it is commonly thought as a "first the request, then the response" protocol - however, that is not the case. It is perfectly possible, for example for a server that echoes back the content bytes that the client sends, to have the client make a large upload, and while the upload is still going the server already starts to respond echoing back the bytes - upload and download happen at the same time.

    We can now enter the matter of unsolicited communication from server to client.

    This is not possible in HTTP/1.1. Even with Server Sent Events (SSE) the client makes a request and the server responds with an "infinite response" - but the client must make the request first.

    In HTTP/1.1, SSE is not full duplex from the point of view of a single TCP connection: the client first makes the request, then the server responds with an "infinite response". From that point on, the client can communicate with the server only by making another request, which means opening a new connection.

    In HTTP/2, SSE is full duplex because it would be possible for the client to communicate to the server by making another request on the same TCP connection, thanks to HTTP/2 multiplexing.

    The SSE "infinite response" can be seen as "the server writes chunks of data that can be interpreted as pushed messages" but the SSE protocol is too simple to allow generic messages from server to client (e.g. data cannot be binary). You would not consider a download that stutters as the server pushing data to the client :)

    Unsolicited communication from server to client is also not possible in HTTP/2, because HTTP/2 can "push" a resource to the client, but only in the context of a previous request.

    For example, a HTTP/2 client establishes a connection with the server, but then it does not send any request; in this case, the server won't be able to push anything to the client (not even a welcome page), as it needs a previous request to do so.

    That is why HTTP/2 cannot be a complete substitute for the WebSocket protocol, which is the only web protocol that you can use for full unsolicited communication from server to client.