6
votes

The new HTTP/2 protocol comes with some promising features. Some of them:

  • Multiplexing - a single TCP connection can be used to make multiple HTTP/2 requests and receive multiple responses (to a single origin)
  • HTTP/2 Server Push - sending server responses to the client without receiving requests, i.e. initiated by the server
  • Bidirectional connection - HTTP/2 spec - Streams and Multiplexing:

A "stream" is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection.

The motivation behind HTTP/2 is explained here HTTP/2 FAQ:

HTTP/1.1 has served the Web well for more than fifteen years, but its age is starting to show.

and

The goal of the Working Group is that typical uses of HTTP/1.x can use HTTP/2 and see some benefit.

So HTTP/2 is nice and comes to replace HTTP/1.x. Unfortunately, HTTP/2 does not support WebSockets. In this question Does HTTP/2 make websockets obsolete? it is made clear that the HTTP/2 Server Push is not an alternative, neither are Server-Sent Events.

Now to the question: What do we use if we want WebSockts functionality over HTTP/2?

3

3 Answers

5
votes

Current forms of HTTP/2 Protocol Negotiation:

HTTP/2 connections start in one of three ways:

  1. In an encrypted connection (TLS/SSL) using ALPN (Application Layer Protocol Negotiation). Most browsers require TLS/SSL for HTTP/2 and use this method for HTTP/2 connection establishment.

  2. In clear text, using the HTTP/1.1 Upgrade header (same as Websockets). Most browsers require TLS/SSL for HTTP/2, so this is limited in it's support.

  3. In clear text, using a special string at the beginning of an HTTP/1.1 connection (which could allow HTTP/2 servers in clear text to disable HTTP/1.1 support). Limited client support.

Negotiating the Websocket Protocol, present tense:

Negotiating Websocket connections, at the moment, requires HTTP/1.1 support and makes use of the HTTP/1.1 Upgrade header.

This is often performed by the same application server that listens to the HTTP/1.1 and HTTP/2 connections. Web applications that support concurrency (whether evented or thread based) are usually protocol agnostic (as long as HTTP semantics are preserved) and work well enough on both protocols.

This allows HTTP data to be used during connection establishment (and perhaps effect the Websocket connection state/authentication procedure).

Once the Websocket connection is established, it's totally independent from the HTTP semantics / layer.

Negotiating the Websocket Protocol in an HTTP/2 world:

In an HTTP/2 (only) world, which might be a while into the future, there could be a number of possible approaches to Websocket protocol negotiation: an ALPN based approach and an HTTP/2 "tunnel" (or "stream") approach.

The ALPN approach preserves protocol independence at the expense of the pre-upgrade (HTTP) stage, while the "stream" approach provides the HTTP pre-"upgrade" (or Connect) stage at the expense of high coupling and complexity.

The ALPN Approach:

One possible future approach will simply add the Websocket protocol to the ALPN negotiation table.

At the moment, ALPN is used to select (or default to) the "http/1.1" protocol and the Upgrade request is handled by the HTTP/1.1 server. Which means that Websocket still provides us with the HTTP header data during protocol negotiation (while using it's own TCP/IP connection)

In the future, ALPN might simply add "wss" as an available choice.

Using this approach, the Websocket (which is currently established using the HTTP/1.1 Upgrade header, both in encrypted and clear text forms) could easily be negotiated using the ALPN extension to the TLS/SSL layer.

This will keep the Websocket protocol independent from the HTTP/2 protocol and allow it's use even when HTTP isn't supported.

However, this will come with the downside that cookies and other HTTP headers might be no longer available as part of the protocol negotiation. Another difference (both good and bad) is that this approach will require a separate TCP/IP connection.

The HTTP/2 "tunnel" / "stream" approach

Another possible future approach, which is reflected in this proposed draft, will dispose of the HTTP/1.1 variation of the Websocket protocol in favor of an HTTP/2 "stream" approach.

HTTP/2 "streams" are the way HTTP/2 implements multiplexing and allows multiple requests to be handled concurrently. Each request receives a stream number ID and any data pertaining to this request (headers, responses etc') is identified using the same numerical stream ID.

Under this approach, "Websocket" data will be contain within the HTTP/2 wrapper and the stream ID will be used to identify the "Websocket" stream.

Although this might provide some benefits (HTTP headers and cookies could be provided as part of the Websocket negotiation), it's not without its downfalls.

Higher complexity and tighter protocol coupling are just two examples, both of which are very serious downfalls.

Conclusion:

At the time of this writing, HTTP/1.1 Upgrade semantics are required for Websocket connections, both when using clear text (ws) and encrypted (wss) connections.

The future is, as of yet, undecided and it will probably take a long time before the current Upgrade process (using HTTP/1.1) is phased out

6
votes

Well your timing is rather apt!

A new version of the internet standards draft was literally just published:

Bootstrapping WebSockets with HTTP/2

Additional information here:

https://github.com/mcmanus/draft-h2ws/blob/master/README.md

And you can follow the discussion in it here:

https://lists.w3.org/Archives/Public/ietf-http-wg/2017OctDec/0032.html

Until this is approved, and then implemented by browsers and servers, I would say that Daniel Haxx’s post that you included in your question represents a very good summary of the current status.

2
votes

One of your links actually has one answer: you can just use SSE.

Semantically, you can achieve the same things with either websockets or (SSE + POST ). The view that the two technologies address different use cases is, roughly speaking, bikeshedding around "this syntax works better for this".

There are ongoing efforts to port something similar to websockets to HTTP/2, but unless those technologies make possible new uses cases or efficiencies, I see no point.