We are amid a big shift of the protocol on which the Internet relies: HTTP. The change raises a lot of questions and concerns and we are hearing and reading a lot of good (and bad) information about HTTP/2. While it has a lot to offer, HTTP/2 doesn’t completely replace the need for existing push/streaming technologies.
The first important thing to notice about HTTP/2 is that it is not a replacement for all of HTTP. The verbs, status codes and most of the headers will remain the same as today. HTTP/2 is about becoming more efficient in the way data is being transferred on the wire.
Let’s take a look at the key differences compared to HTTP 1.x and what issue each improvement is addressing:
- HTTP/2 is a binary protocol where HTTP 1.x is textual. Binary protocols are more efficient to parse because there is only one code path where HTTP 1.x defines 4 different ways to parse a message. Binary protocols are also more space efficient on the wire. In return, it is more difficult for humans to deal with them, as they are not human-readable. A tradeoff.
- HTTP/2 is multiplexed to tackle a known limitation in networking known as head-of-line blocking (HOL Blocking). This problem can occur with HTTP 1.1 when multiple requests are issued on a single TCP connection (aka HTTP pipelining). As the entire connection is ordered and blocking (FIFO), a slow request can hold up the connection, slowing down all subsequent requests. Multiplexing definitively solve this problem by allowing several request and response to fly on the wire at the same time.
- HTTP/2 uses header compression to reduce overhead. Typical header sizes of 1KB are common mainly because of the cookies that we all have to accept for a smooth user experience. Transferring 1KB can take several network round trips just to exchange headers, and those headers are being re-sent every time because of the stateless nature of HTTP 1.x. The TCP Slow-start makes the problem even worse by limiting the number of packets that can be sent during the first round trips until TCP effectively finishes to probe the network to figure out the available capacity and properly adapt its congestion window. In this context, compressing headers significantly limits the number of required round trips.
- HTTP/2 Server Push allows servers to proactively send responses into client caches. In a typical HTTP 1.x workflow, the browser requests a page, the server sends the HTML in the response, and then needs to wait for the browser to parse the response and issue additional requests to fetch the additional embedded assets (JavaScript, CSS, etc.). Server push allows the server to speculatively start sending resources to the client. Here, the browser does not have to parse the HTML page and find out which other resources to load; instead the server can start sending them immediately.
Now, if we compare HTTP/2 against WebSocket, we can see a lot of similarities:
HTTP/2 |
WebSocket |
|
Headers |
Compressed (HPACK) |
None |
Binary |
Yes |
Binary or Textual |
Multiplexing |
Yes |
Yes |
Prioritization |
Yes |
No |
Compression |
Yes |
Yes |
Direction |
Client/Server + Server Push |
Bidirectional |
Full-duplex |
Yes |
Yes |
Given these improvements and similar capabilities, it is natural to ask: is HTTP/2 a replacement for push technologies such as WebSocket or SSE?
Well, the answer is clearly no, for a simple reason: As we have seen above, HTTP/2 introduces Server Push which enables the server to proactively send resources to the client cache. It does not, however, allow for pushing data down to the client application itself. Server pushes are only processed by the browser and do not pop up to the application code, meaning there is no API for the application to get notifications for those events.
This is where Server-Sent Events (SSE) becomes very useful. SSE is a mechanism that allows the server to asynchronously push the data to the client once the client-server connection is established. The server can then decide to send data whenever a new “chunk” of data is available. It can be considered as a one-way publish-subscribe model. It also offers a standard JavaScript client API named EventSource implemented in most modern browser as part of HTML5 standard by W3C. Note that browsers that do not support EventSource API can be easily polyfilled.
Since SSE is based on HTTP, it has a natural fit with HTTP/2 and can be combined to get the best of both: HTTP/2 handling an efficient transport layer based on multiplexed streams and SSE providing the API up to the applications to enable push.
To fully understand what Streams and Multiplexing are all about, let’s have a look first at the IETF definition: a "stream" is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection. One of its main characteristics is that a single HTTP/2 connection can contain multiple concurrently open streams, with either endpoint interleaving frames from multiple streams.
To avoid having you read the above definition a second time to make sure you fully understood it (did it myself :-)), this schema from Nginx blog clearly explains it:
If you want to experiment HTTP/2 Multiplexing at work, try this demo while having a developer terminal open on your favorite browser. If you are not sure that your favorite browser is HTTP/2 compatible yet, have a quick look here.
Using HTTP/1 you should get something like this:
The browsers opens several HTTP 1.x connections in parallel to speedup the page loading. Browsers have different limits on maximum concurrent connections they can open on a domain but they generally support around 6 different connections. To overcome this limitation, techniques such as Domain sharding can be used to distribute resources across several domains. These techniques (that we can consider as hacks) including concatenating JavaScript and CSS files, spriting images and resource inlining will be counter-productive in a HTTP/2 world. This is probably one of the main impacts when considering to switch to HTTP/2: eliminate optimization/hacks made during several years.
When trying with HTTP/2, we see the browser use a single multiplexed connection with a much faster load time.
Now that we have understood what multiplexing is all about, we have to remember that SSE is HTTP based. It means that with HTTP/2, not only can several SSE streams be interleaved onto a single TCP connection, but also several SSE streams (server to client push) with several client requests (client to server). Thanks to HTTP/2 and SSE, we now have a pure HTTP bidirectional connection with a simple API to let application code register to server pushes. Lack of bidirectional capabilities have often been perceived as a major drawback when comparing SSE to WebSocket. Thanks to HTTP/2 is it no longer the case. This opens up the opportunity to skip WebSockets and stick to a HTTP based signaling.
To provide some answers to the initial question: Will WebSocket survive HTTP/2?
It certainly will, mainly because it is already well adopted and, in very specific use cases, it has an advantage as it has been built from the ground up for bidirectional capabilities with less overhead (headers). Let's say that you need to exchange a high throughput of messages from both ends, with almost as much data flow upstream than downstream (e.g Massively Multiplayer Online Game that needs to keep all their players in sync). WebSocket will probably remain a better choice.
If you consider a use case like displaying real-time market news, market data, chat application, etc, relying on HTTP/2 + SSE will provide you an efficient bidirectional communication channel and keep the huge advantage of staying in the HTTP world:
- WebSocket can often be a source of pain when considering compatibility with existing web infrastructure as it upgrades an HTTP connection to a completely different protocol that has nothing to do with HTTP.
- Scale and security: Web components (Firewalls, Intrusion Detection, Load Balancers) are built, maintained and configured with HTTP in mind, an environment that large/critical applications will prefer in terms of resiliency, security and scalability.
Takeaways
- HTTP/2 is not a full replacement of HTTP.
- Hacks such as Domain sharding, resource inlining and image spriting will be counter-productive in an HTTP/2 world.
- HTTP/2 is not a replacement for push technologies such as WebSocket or SSE.
- HTTP/2 Push server can only be processed by browsers, not by applications.
- Combining HTTP/2 and SSE provides efficient HTTP-based bidirectional communication.
WebSocket will probably remain used but SSE and its EventSource API combined with the power of HTTP/2 will provide the same result in most use cases, just simpler.
About the Author
Allan Denis has more than 10 years of experience in wireless communications and distributed computing. In his spare time, he enjoys riding his bike in the Alpes valleys in France. Allan is CTO at Streamdata.io.