WebSocket 是什麼原理?爲何能夠實現持久鏈接?

你能夠把 WebSocket 當作是 HTTP 協議爲了支持長鏈接所打的一個大補丁,它和 HTTP 有一些共性,是爲了解決 HTTP 自己沒法解決的某些問題而作出的一個改良設計。在之前 HTTP 協議中所謂的 keep-alive connection 是指在一次 TCP 鏈接中完成多個 HTTP 請求,可是對每一個請求仍然要單獨發 header;所謂的 polling 是指從客戶端(通常就是瀏覽器)不斷主動的向服務器發 HTTP 請求查詢是否有新數據。這兩種模式有一個共同的缺點,就是除了真正的數據部分外,服務器和客戶端還要大量交換 HTTP header,信息交換效率很低。它們創建的「長鏈接」都是僞.長鏈接,只不過好處是不須要對現有的 HTTP server 和瀏覽器架構作修改就能實現。

WebSocket 解決的第一個問題是,經過第一個 HTTP request 創建了 TCP 鏈接以後,以後的交換數據都不須要再發 HTTP request了,使得這個長鏈接變成了一個真.長鏈接。可是不須要發送 HTTP header就能交換數據顯然和原有的 HTTP 協議是有區別的,因此它須要對服務器和客戶端都進行升級才能實現。在此基礎上 WebSocket 仍是一個雙通道的鏈接,在同一個 TCP 鏈接上既能夠發也能夠收信息。此外還有 multiplexing 功能,幾個不一樣的 URI 能夠複用同一個 WebSocket 鏈接。這些都是原來的 HTTP 不能作到的。

另外說一點技術細節,由於看到有人提問 WebSocket 可能進入某種半死不活的狀態。這實際上也是原有網絡世界的一些缺陷性設計。上面所說的 WebSocket 真.長鏈接雖然解決了服務器和客戶端兩邊的問題,但坑爹的是網絡應用除了服務器和客戶端以外,另外一個巨大的存在是中間的網絡鏈路。一個 HTTP/WebSocket 鏈接每每要通過無數的路由,防火牆。你覺得你的數據是在一個「鏈接」中發送的,實際上它要跨越千山萬水,通過無數次轉發,過濾,才能最終抵達終點。在這過程當中,中間節點的處理方法極可能會讓你意想不到。

好比說,這些坑爹的中間節點可能會認爲一份鏈接在一段時間內沒有數據發送就等於失效,它們會自做主張的切斷這些鏈接。在這種狀況下,不論服務器仍是客戶端都不會收到任何提示,它們只會一廂情願的覺得彼此間的紅線還在,徒勞地一邊又一邊地發送抵達不了彼岸的信息。而計算機網絡協議棧的實現中又會有一層套一層的緩存,除非填滿這些緩存,你的程序根本不會發現任何錯誤。這樣,原本一個美好的 WebSocket 長鏈接,就可能在絕不知情的狀況下進入了半死不活狀態。

而解決方案,WebSocket 的設計者們也早已想過。就是讓服務器和客戶端可以發送 Ping/Pong Frame(RFC 6455 - The WebSocket Protocol)。這種 Frame 是一種特殊的數據包,它只包含一些元數據而不須要真正的 Data Payload,能夠在不影響 Application 的狀況下維持住中間網絡的鏈接狀態。html

相關文章
相關標籤/搜索