- 問題一
- 問題二
- 最後
- 《Netty 實作原理與源碼解析 —— 精品合集》
- 《Spring 實作原理與源碼解析 —— 精品合集》
- 《MyBatis 實作原理與源碼解析 —— 精品合集》
- 《Spring MVC 實作原理與源碼解析 —— 精品合集》
- 《Spring Boot 實作原理與源碼解析 —— 精品合集》
- 《資料庫實體設計合集》
- 《Java 面試題 —— 精品合集》
- 《Java 學習指南 —— 精品合集》
最近公司内部同僚分享了WebSocket相關的一些知識,之前也用過WebSocket做過一個即時通信的應用。基本上但凡提到WebSocket和HTTP的關系都會有以下兩條:
- WebSocket和HTTP都是基于TCP協定的兩個不同的協定
- WebSocket依賴于HTTP連接配接
作為結論性的總結,直接了當,但是我需要更多的實作細節來解釋上述結論。 因為都是基于TCP的兩個獨立的協定,WebSocket按理說可以和HTTP沒有關系,是以這裡面包含兩個問題:
- WebSocket依賴于HTTP連接配接,那麼它如何從連接配接的HTTP協定轉化為WebSocket協定?
- WebSocket為什麼要依賴于HTTP協定的連接配接?
問題一
幸運的是,第一個問題的答案很容易找到。
每個WebSocket連接配接都始于一個HTTP請求。 具體來說,WebSocket協定在第一次握手連接配接時,通過HTTP協定在傳送WebSocket支援的版本号,協定的字版本号,原始位址,主機位址等等一些列字段給伺服器端:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Version: 13
注意,關鍵的地方是,這裡面有個Upgrade首部,用來把目前的HTTP請求更新到WebSocket協定,這是HTTP協定本身的内容,是為了擴充支援其他的通訊協定。 如果伺服器支援新的協定,則必須傳回101:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
至此,HTTP請求物盡其用,如果成功出發onopen事件,否則觸發onerror事件,後面的傳輸則不再依賴HTTP協定。 總結一下,這張圖比較貼切:
問題二
經過學習和了解,我認為有兩點:
第一,WebSocket設計上就是天生為HTTP增強通信(全雙工通信等),是以在HTTP協定連接配接的基礎上是很自然的一件事,并是以而能獲得HTTP的諸多便利。 第二,這諸多便利中有一條很重要,基于HTTP連接配接将獲得最大的一個相容支援,比如即使伺服器不支援WebSocket也能建立HTTP通信,隻不過傳回的是onerror而已,這顯然比伺服器無響應要好的多。
最後
關于WebSocket和HTTP的讨論其實網上并不少,但因為一些資料本身就邏輯混亂,往往看的越多可能對于它們的關系越糊塗。 理清一下這個簡單的關系對于了解它們的應用場景還是有必要的,這也是我做這個分析的出發點所在。