websocket以及http的區別筆記

高壓鍋發表於2018-07-30

區別

'http'

HTTP1.1預設使用持久連線(persistent connection),在一個TCP連線上也可以傳輸多個Request/Response訊息對,但是HTTP的基本模型還是一個Request對應一個Response

連結方式:主要有幾種

  • 輪詢(polling),輪詢就會造成對網路和通訊雙方的資源的浪費,且非實時。
  • 長輪詢,客戶端傳送一個超時時間很長的Request,伺服器hold住這個連線,在有新資料到達時返回Response,相比1,佔用的網路頻寬少了,其他類似。穩定性有待考究
  • 長連線,其實有些人對長連線的概念是模糊不清的,我這裡講的其實是HTTP的長連線(1)
  • 如果你使用Socket來建立TCP的長連線(2)

  • 那麼,這個長連線(2)跟我們這裡要討論的WebSocket是一樣的,實際上TCP長連線就是WebSocket的基礎,但是如果是HTTP的長連線,本質上還是Request/Response訊息對,仍然會造成資源的浪費、實時性不強等問題。

    長連結

websocket的協議基礎基於http 握手+傳輸

而真正在WS的握手過程中起到作用的是下面幾個header域。
1 Upgrade:upgrade是HTTP1.1中用於定義轉換協議的header域。它表示,如果伺服器支援的話,客戶端希望使用現有的「網路層」已經建立好的這個「連線(此處是TCP連線)」,切換到另外一個「應用層」(此處是WebSocket)協議。

2 Connection:HTTP1.1中規定Upgrade只能應用在「直接連線」中,所以帶有Upgrade頭的HTTP1.1訊息必須含有Connection頭,因為Connection頭的意義就是,任何接收到此訊息的人(往往是代理伺服器)都要在轉發此訊息之前處理掉Connection中指定的域(不轉發Upgrade域)。
如果客戶端和伺服器之間是通過代理連線的,那麼在傳送這個握手訊息之前首先要傳送CONNECT訊息來建立直接連線。

3 Sec-WebSocket-*:第7行標識了客戶端支援的子協議的列表(關於子協議會在下面介紹),第8行標識了客戶端支援的WS協議的版本列表,第5行用來傳送給伺服器使用(伺服器會使用此欄位組裝成另一個key值放在握手返回資訊裡傳送客戶端)。

4 Origin:作安全使用,防止跨站攻擊,瀏覽器一般會使用這個來標識原始域。

複製程式碼
  • WebSocket協議Uri
1 如果上一步中的TCP連線建立失敗,則此WebSocket連線失敗。
2 如果協議是wss,則在上一步建立的TCP連線之上,使用TSL傳送握手資訊。如果失敗,則此WebSocket連線失敗;如果成功,則以後的所有資料都要通過此TSL通道進行傳送。
複製程式碼
  • WebSocket使用注意點

服務端 如果請求是HTTPS,則首先要使用TLS進行握手,如果失敗,則關閉連線,如果成功,則之後的資料都通過此通道進行傳送

之後服務端可以進行一些客戶端驗證步驟

如果一切都成功,則返回成功的Response握手訊息。

  • 服務端傳送的成功的Response握手

Upgrade頭域,內容為websocket

Connection頭域,內容為Upgrade

Sec-WebSocket-Accept頭域,其內容的生成步驟:

首先將Sec-WebSocket-Key的內容加上字串258EAFA5-E914-47DA-95CA-C5AB0DC85B11(一個UUID)。

將#1中生成的字串進行SHA1編碼。

將#2中生成的字串進行Base64編碼。

  • Sec-WebSocket-Protocol頭域(可選)
  • Sec-WebSocket-Extensions頭域(可選)
與HTTP比較
同樣作為應用層的協議,WebSocket在現代的軟體開發中被越來越多的實踐,和HTTP有很多相似的地方,這裡將它們簡單的做一個純個人、非權威的比較:

相同點:
都是基於TCP的應用層協議。
都使用Request/Response模型進行連線的建立。
在連線的建立過程中對錯誤的處理方式相同,在這個階段WS可能返回和HTTP相同的返回碼。
都可以在網路中傳輸資料。

不同點:
WS使用HTTP來建立連線,但是定義了一系列新的header域,這些域在HTTP中並不會使用。
WS的連線不能通過中間人來轉發,它必須是一個直接連線。
WS連線建立之後,通訊雙方都可以在任何時刻向另一方傳送資料。
WS連線建立之後,資料的傳輸使用幀來傳遞,不再需要Request訊息。
WS的資料幀有序。
```複製程式碼

相關文章