{"id":8977,"date":"2016-06-15T13:55:11","date_gmt":"2016-06-15T11:55:11","guid":{"rendered":"https:\/\/daniel.haxx.se\/blog\/?p=8977"},"modified":"2016-06-15T13:55:11","modified_gmt":"2016-06-15T11:55:11","slug":"no-websockets-over-http2","status":"publish","type":"post","link":"https:\/\/daniel.haxx.se\/blog\/2016\/06\/15\/no-websockets-over-http2\/","title":{"rendered":"No websockets over HTTP\/2"},"content":{"rendered":"<p><strong>There is no websockets for HTTP\/2<\/strong>.<\/p>\n<p>By this, I mean that there&#8217;s no way to negotiate or upgrade a connection to websockets over HTTP\/2 like there is for HTTP\/1.1 as expressed by <a href=\"https:\/\/tools.ietf.org\/html\/rfc6455\">RFC 6455<\/a>. That spec details how a client can use Upgrade: in a HTTP\/1.1 request to switch that connection into a websockets connection.<\/p>\n<p>Note that websockets is not part of the HTTP\/1 spec, it just uses a HTTP\/1 protocol detail to switch an HTTP connection into a websockets connection. Websockets over HTTP\/2 would similarly not be a part of the HTTP\/2 specification but would be separate.<\/p>\n<p>(As a side-note, that Upgrade: mechanism is the same mechanism a HTTP\/1.1 connection can get <a href=\"http:\/\/httpwg.org\/specs\/rfc7540.html#discover-http\">upgraded to HTTP\/2<\/a> if the server supports it &#8211; when not using HTTPS.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1918\" src=\"https:\/\/daniel.haxx.se\/blog\/wp-content\/uploads\/2010\/08\/chinese-socket.jpg\" alt=\"chinese-socket\" width=\"345\" height=\"330\" srcset=\"https:\/\/daniel.haxx.se\/blog\/wp-content\/uploads\/2010\/08\/chinese-socket.jpg 345w, https:\/\/daniel.haxx.se\/blog\/wp-content\/uploads\/2010\/08\/chinese-socket-150x143.jpg 150w, https:\/\/daniel.haxx.se\/blog\/wp-content\/uploads\/2010\/08\/chinese-socket-300x286.jpg 300w\" sizes=\"auto, (max-width: 345px) 100vw, 345px\" \/><\/p>\n<h2>Draft<\/h2>\n<p>There&#8217;s was once a <a href=\"https:\/\/tools.ietf.org\/html\/draft-hirano-httpbis-websocket-over-http2-01\">draft<\/a> submitted that describes how websockets over HTTP\/2 could&#8217;ve been done. It didn&#8217;t get any particular interest in the IETF HTTP working group back then and as far as I&#8217;ve seen, there has been very little general interest in any group to pick up this dropped ball and continue running. It just didn&#8217;t go any further.<\/p>\n<p>This is important: <strong>the lack of websockets over HTTP\/2 is because nobody has produced a spec<\/strong> (and implementations) to do websockets over HTTP\/2. Those things don&#8217;t happen by themselves, they actually require a bunch of people and implementers to believe in the cause and work for it.<\/p>\n<p>Websockets over HTTP\/2 could of course have the benefit that it would only be one stream over the connection that could serve regular non-websockets traffic at the same time in many other streams, while websockets upgraded on a HTTP\/1 connection uses the entire connection exclusively.<\/p>\n<h2>Instead<\/h2>\n<p>So what do users do instead of using websockets over HTTP\/2? Well, there are several options. You probably either stick to HTTP\/2, upgrade from HTTP\/1, use Web push or go the WebRTC route!<\/p>\n<p>If you really need to stick to websockets, then you simply have to upgrade to that from a HTTP\/1 connection &#8211; just like before. Most people I&#8217;ve talked to that are stuck really hard on using websockets are app developers that basically only use a single connection anyway so doing that HTTP\/1 or HTTP\/2 makes no meaningful difference.<\/p>\n<p>Sticking to HTTP\/2 pretty much allows you to go back and use the <a href=\"https:\/\/tools.ietf.org\/html\/rfc6202\">long-polling tricks<\/a> of the past before websockets was created. They were once rather bad since they would waste a connection and be error-prone since you&#8217;d have a connection that would sit idle most of the time. Doing this over HTTP\/2 is much less of a problem since it&#8217;ll just be a single stream that won&#8217;t be used that much so it isn&#8217;t that much of a waste. Plus, the connection may very well be used by other streams so it will be less of a problem with idle connections getting killed by NATs or firewalls.<\/p>\n<p>The <a href=\"https:\/\/www.w3.org\/TR\/push-api\/\">Web Push API<\/a> was brought by W3C during 2015 and is in many ways a more &#8220;webby&#8221; way of doing push than the much more manual and &#8220;raw&#8221; method that websockets is. If you use websockets mostly for push notifications, then this might be a more convenient choice.<\/p>\n<p>Also introduced after websockets, is <a href=\"http:\/\/w3c.github.io\/webrtc-pc\/\">WebRTC<\/a>. This is a technique introduced for communication between browsers, but it certainly provides an alternative to some of the things websockets were once used for.<\/p>\n<h2>Future<\/h2>\n<p>Websockets over HTTP\/2 <em>could<\/em> still be done. The fact that it isn&#8217;t done just shows that there isn&#8217;t enough interest.<\/p>\n<h2>Non-TLS<\/h2>\n<p>Recall how browsers only speak <a href=\"https:\/\/daniel.haxx.se\/blog\/2015\/03\/06\/tls-in-http2\/\">HTTP\/2 over TLS<\/a>, while websockets can also be done over plain TCP. In fact, the only way to upgrade a HTTP connection to websockets is using the HTTP\/1 Upgrade: header trick, and not the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Application-Layer_Protocol_Negotiation\">ALPN method for TLS<\/a> that HTTP\/2 uses to reduce the number of round-trips required.<\/p>\n<p>If anyone would introduce websockets over HTTP\/2, they would then probably only be possible to be made over TLS from within browsers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There is no websockets for HTTP\/2. By this, I mean that there&#8217;s no way to negotiate or upgrade a connection to websockets over HTTP\/2 like there is for HTTP\/1.1 as expressed by RFC 6455. That spec details how a client can use Upgrade: in a HTTP\/1.1 request to switch that connection into a websockets connection. &hellip; <a href=\"https:\/\/daniel.haxx.se\/blog\/2016\/06\/15\/no-websockets-over-http2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">No websockets over HTTP\/2<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,6,45],"tags":[230,369,287],"class_list":["post-8977","post","type-post","status-publish","format-standard","hentry","category-net","category-floss","category-web","tag-http","tag-http2","tag-websockets"],"_links":{"self":[{"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/posts\/8977","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/comments?post=8977"}],"version-history":[{"count":20,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/posts\/8977\/revisions"}],"predecessor-version":[{"id":9039,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/posts\/8977\/revisions\/9039"}],"wp:attachment":[{"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/media?parent=8977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/categories?post=8977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daniel.haxx.se\/blog\/wp-json\/wp\/v2\/tags?post=8977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}