本文轉載自:衆成翻譯
譯者:文藺
連接:http://www.zcfy.cc/article/657
原文:https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/html譯者注: 《深刻淺出 Node.js》第七章講述 WebSocket 服務的構建中,對本文中反覆提到的
Upgrade
有比較詳細的說明。git
NO WEBSOCKETS OVER HTTP/2.github
我這樣說的意思是,在 HTTP/2 協議裏,沒法像在 HTTP/1.1 中把鏈接(connection)協商或提高爲 WebSocket那樣,如RFC 6455 所描述的 —— 這個規範(RFC 6455)詳述了在一個 HTTP/1.1 請求中,客戶端如何使用 Upgrade:
將連 http 接轉換爲 WebSocket 鏈接。web
注意 WebSocket 並不是 HTTP/1 規範的一部分,它只是使用了 HTTP/1 的協議細節將 HTTP 鏈接轉換爲 WebSocket 鏈接。 相似地,HTTP/2 之上的 WebSocket 也不會成爲 HTTP/2 規範的一部分,而是成爲獨立的一部分。api
(附註:Upgrade:
的機制,和在服務端支持的狀況下,非 https 的HTTP/1.1 鏈接能升級爲 HTTP/2 是同樣的。)瀏覽器
曾經有一份提交的草案描述了 HTTP/2 下的 WebSocket 如何實現。那時 IETF 工做組並無對它表現出任何特別的興趣,並且在我看來,不多有工做組有興趣撿起這個球把它繼續滾下去。它就這樣,毫無進展了。websocket
這很重要: HTTP/2 下 WebSocket 的缺失,是由於根本沒人寫出來一份規範 (及其實現)。這些事情不會本身發生,它們須要一羣相信這份事業併爲之努力工做的人。socket
HTTP/2 下 WebSocket 固然有好處,它只是鏈接上的一個數據流,這個鏈接同時也能服務於其餘的非 WebSocket 的通訊。而 HTTP/1 鏈接升級的 WebSocket 獨佔了整個鏈接。spa
因此 HTTP/2 下面咱們拿什麼來替代 WebSocket 呢?好吧,也有幾個選擇。可能的狀況是,你要麼堅持着 HTTP/2, 從 HTTP/1 升級,使用 Web 推送(Web push),要麼就走到 WebRTC 這條路上來。翻譯
若是你真的必需要堅持使用 WebSocket, 那很簡單,你只須要像以前同樣,從 HTTP/1 鏈接升級到 WebSocket。和我交談過的大部分很是堅持 WebSocket的人都是那些開發者,他們就只須要很基本的單一的鏈接,因此 HTTP/1 和 HTTP/2 對他們來講沒什麼差異。
若是真的很是堅持使用 HTTP/2,你能夠像過去使用 長輪詢那樣,那會兒 WebSocket 還沒被髮明出來。這曾經是挺糟糕的方案,由於會浪費一個鏈接,並且有一個大部分時間是空閒着的鏈接也容易致使錯誤。在 HTTP/2 下面這樣作,問題就少了不少,由於它只是一個不會被使用得太多的單向流,因此不會形成太多浪費。此外,鏈接極可能爲其餘數據流使用,這能減小空閒鏈接被 NATs 或防火牆幹掉的問題。
Web Push API 是 W3C 2015年帶來的一個和 WebSocket 這樣人工化的、「粗糙」的方式相比, 更有 Web 範兒的(more 「webby」)推送方式。若是你主要是拿 WebSocket 來推送消息通知,這多是更方便的選擇。
WebSocket 以後引入的是 WebRTC。這是用來解決瀏覽器之間通訊的,不過拿過來作 WebSocket 曾被拿來作過的一些事情確定也是一種選擇。
HTTP/2 下的 WebSocket 可能 仍是會被實現。它沒被完成的實際狀況,只能代表人們尚未足夠的興趣。
想想,瀏覽器只能在 TLS 之上使用 HTTP/2,而 WebSocket 只需經過普通的 TCP 鏈接就能完成。實際上,將 HTTP 鏈接提高到 WebSocket 的惟一途徑就是使用 HTTP/1 中 Upgrade:
響應頭的小把戲,而不是 HTTP/2 爲了減小須要的往返數量而使用的用於 TSL 的應用層協議(ALPN)的辦法(ALPN method for TLS)。
若是真有人要把 WebSocket 引入到 HTTP/2 中,他們極可能只能經過瀏覽器內部使用 TLS 來實現。