WebSocket與http長鏈接的區別

前言

事先說明這是鄙人看了一點入門文章總結的粗淺的知識, 並不保證理解徹底正確,用來給本身知識梳理用。html

websocket鏈接過程概述

WebSocket 創建鏈接須要先經過一個 http 請求進行和服務端握手。握手經過後鏈接就創建並保持了。
瀏覽器先發送請求:web

GET / HTTP/1.1
Host: localhost:8080
Origin: [url= http://127.0.0.1:3000] http://127.0.0.1:3000[/url]
Connection: Upgrade
Upgrade: WebSocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==

服務端返回一個請求:ajax

HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Upgrade: WebSocket
Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=

這樣握手就完成了(具體 http 請求頭和返回頭各個字段的含義我就懶得寫了,網上一搜一大把,譬如http://www.52im.net/thread-13...)。此時這個鏈接並不會斷掉,而瀏覽器和服務端能夠用這個鏈接相互發消息。(可是這個時候鏈接就不是 http 鏈接而是升級成了 WebSocket 鏈接。瀏覽器和服務端相互發送的不是 http 請求。這裏先說明下,接下來咱們來看下 http 長鏈接是怎麼回事)。瀏覽器

http長鏈接類型

keep-alive

http1.1 出了新頭,若是請求頭中包含 keep-alive,那麼這個 http 請求發送收到返回以後,底層的 tcp 鏈接不會立馬斷掉,若是後續有 http 請求仍是會利用。可是這個鏈接保持一來是沒有硬性規定時間的,由瀏覽器和服務端實現來控制。二來這個鏈接不斷是指底層 tcp 鏈接,不是說一次 http 請求收到返回以後不會斷掉,還能再收服務端的返回(若是服務端對此次 http 請求立馬返回,那麼此次 http 請求就結束了。http 請求和底層 tcp 鏈接的關係後面再說)。這種不是應用層面的長鏈接,其實和模擬 WebSocket 沒啥關係。服務器

comet

這種技術是一種 hack 技術,即瀏覽器發送一個 http 請求,可是服務端不是立馬返回,服務端一直不返回直到有瀏覽器須要的內容了在返回。期間這個 http 請求能夠連着維持比較長的時間(在服務端返回以前)。這樣模擬一種服務端推送機制。由於瀏覽器請求的時候等於先把鏈接創建好,等服務端有消息須要返回時再返回給瀏覽器。websocket

websocket和http長鏈接的區別

先說 comet 和 WebSocket 表現的區別:
comet 發送 http 請求後服務端若是沒有返回則鏈接是一直連着的,等服務端有東西要「推送」給瀏覽器時,至關於給以前發送的這個 http 請求回了一個 http 響應。而後這個保持的時間比較長的 http 鏈接就斷了。而後瀏覽器再次發送一個 http 請求,服務器端再 hold 住不返回,等待有東西須要「推送」給瀏覽器時,再給這個 http 請求一個響應,而後斷開鏈接。循環往復。一旦瀏覽器不給服務器發送 http 請求,那麼服務器是不能主動給瀏覽器推送消息的,由於根本沒有連着的鏈接給你推。網絡

WebSocket 則不一樣,它握手後創建的鏈接是不會斷的(除了意外狀況和程序主動掐斷)。不須要瀏覽器在每次收到服務器推送的消息後再發起請求。並且服務器端能夠隨時給瀏覽器推送消息,不須要等瀏覽器發 http 請求,由於 WebSocket 的鏈接一直在沒斷。socket

爲何會有這樣的區別?tcp

這是協議層面的區別。http 協議規定了 http 鏈接是一個一來(request)一回(response)的過程。一個請求得到一個響應後必須斷掉。並且只有先有請求才會有響應。拿 http1.1 keep-alive 來講,即便底層 tcp 鏈接沒有斷,服務端平白無故給瀏覽器發一個 http 響應,瀏覽器是不收的,他找不到收的人啊,由於這個響應沒有對應的請求。你看 ajax 必須先發請求才會有一個 onsuccess 回調來響應這個請求。這個 onsuccess 的回調會在你 ajax 不發送的狀況下被調用到嗎?url

而 WebSocket 協議不一樣,他經過握手以後規定說你鏈接給我保持着,別斷咯。因此瀏覽器服務器在這種狀況下能夠相互的發送消息。瀏覽器端 new 一個 WebSocket 以後註冊 onmessage 回調,那麼這個 onmessage 能夠被反覆調用,只要服務器端有消息過來。而不會說是 new 一個 WebSocket onmessage 只會被調用一次,下次還得再 new 一個 websocket。

上面說到 http 鏈接,tcp 鏈接,websockt 鏈接到底啥區別。其實這是新人最容易搞不懂的地方。接下來我就要胡謅了,爲啥說胡謅,由於我只是看了個皮毛,而後按我本身的理解說下區別。網絡5層分層(自下而上):

  1. 物理層
  2. 數據鏈路層
  3. 網絡層
  4. 傳輸層
  5. 應用層

http,websocket都是應用層協議,他們規定的是數據怎麼封裝,而他們傳輸的通道是下層提供的。就是說不管是 http 請求,仍是 WebSocket 請求,他們用的鏈接都是傳輸層提供的,即 tcp 鏈接(傳輸層還有 udp 鏈接)。只是說 http1.0 協議規定,你一個請求得到一個響應後,你要把鏈接關掉。因此你用 http 協議發送的請求是沒法作到一直連着的(若是服務器一直不返回也能夠保持至關一段時間,可是也會有超時而被斷掉)。而 WebSocket 協議規定說等握手完成後咱們的鏈接不能斷哈。雖然 WebSocket 握手用的是 http 請求,可是請求頭和響應頭裏面都有特殊字段,當瀏覽器或者服務端收到後會作相應的協議轉換。因此 http 請求被 hold 住不返回的長鏈接和 WebSocket 的鏈接是有本質區別的。

參考資料

  1. WebSocket 規範:https://tools.ietf.org/html/r...
  2. 《Http、TCP/IP協議與Socket之間的區別》https://blog.csdn.net/done58/...
相關文章
相關標籤/搜索