看完讓你完全搞懂Websocket原理

Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。web

首先咱們來看個典型的 Websocket 握手(借用Wikipedia的。。)ajax

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket //這個就是Websocket的核心了,告訴  、  等服務器:注意啦,我發起的是Websocket協議,快點幫我找到對應的助理處理~不是那個老土的HTTP。
Connection: Upgrade//
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==// 是一個  的值,這個是瀏覽器隨機生成的驗證是否是真的是Websocket助理
Sec-WebSocket-Protocol: chat, superchat// 是一個用戶定義的字符串,用來區分同URL下,不一樣的服務所須要的協議。簡單理解:今晚我要服務A,別搞錯啦~
Sec-WebSocket-Version: 13// 是告訴服務器所使用的 (協議版本
Origin: http://example.comApacheNginxSec-WebSocket-KeyBase64 encodeSec_WebSocket-ProtocolSec-WebSocket-VersionWebsocket Draft

而後服務器會返回下列東西,表示已經接受到請求, 成功創建Websocket啦!瀏覽器

 

HTTP/1.1 101 Switching Protocols
Upgrade: websocket//這裏開始就是HTTP最後負責的區域了,告訴客戶,我已經成功切換協議啦~
Connection: Upgrade//
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=// 這個則是通過服務器確認,而且加密事後的  。服務器:好啦好啦,知道啦,給你看個人ID CARD來證實行了吧
Sec-WebSocket-Protocol: chat// 則是表示最終使用的協議Sec-WebSocket-AcceptSec-WebSocket-KeySec-WebSocket-Protocol

Websocket的做用服務器

在講Websocket以前,我就順帶着講下 long poll 和 ajax輪詢 的原理websocket

ajax輪詢

ajax輪詢的原理很是簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。併發

long poll

long poll 其實原理跟 ajax輪詢 差很少,都是採用輪詢的方式,不過採起的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發起鏈接後,若是沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完以後,客戶端再次創建鏈接,周而復始socket

 

從上面能夠看出其實這兩種方式,都是在不斷地創建HTTP鏈接,而後等待服務端處理,能夠體現HTTP協議的另一個特色,被動性。何爲被動性呢,其實就是,服務端不能主動聯繫客戶端,只能有客戶端發起。ide

簡單地說就是,服務器是一個很懶的冰箱(這是個梗)(不會、不能主動發起鏈接),可是上司有命令,若是有客戶來,無論多麼累都要好好接待。加密

說完這個,咱們再來講一說上面的缺陷(原諒我廢話這麼多吧OAQ)spa

從上面很容易看出來,無論怎麼樣,上面這兩種都是很是消耗資源的。

ajax輪詢 須要服務器有很快的處理速度和資源。(速度)long poll 須要有很高的併發,也就是說同時接待客戶的能力。(場地大小)

因此 ajax輪詢 和 long poll 都有可能發生這種狀況。

 

因此在這種狀況下出現了,Websocket出現了。他解決了HTTP的這幾個難題。首先,被動性,當服務器完成協議升級後(HTTP->Websocket),服務端就能夠主動推送信息給客戶端啦只須要通過一次HTTP請求,就能夠作到源源不斷的信息傳送了。(在程序設計中,這種設計叫作回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你 )

這樣的協議解決了上面同步有延遲,並且還很是消耗資源的這種狀況。那麼爲何他會解決服務器上消耗資源的問題呢?

其實咱們所用的程序是要通過兩層代理的,即HTTP協議在Nginx等服務器的解析下,而後再傳送給相應的Handler(PHP等)來處理。簡單地說,咱們有一個很是快速的 接線員(Nginx) ,他負責把問題轉交給相應的 客服(Handler) 。

自己接線員基本上速度是足夠的,可是每次都卡在客服(Handler)了,老有客服處理速度太慢。,致使客服不夠。Websocket就解決了這樣一個難題,創建後,能夠直接跟接線員創建持久鏈接,有信息的時候客服想辦法通知接線員,而後接線員在統一轉交給客戶。

這樣就能夠解決客服處理速度過慢的問題了。

同時,在傳統的方式上,要不斷的創建,關閉HTTP協議,因爲HTTP是非狀態性的,每次都要從新傳輸 identity info (鑑別信息),來告訴服務端你是誰。

雖然接線員很快速,可是每次都要聽這麼一堆,效率也會有所降低的,同時還得不斷把這些信息轉交給客服,不但浪費客服的處理時間,並且還會在網路傳輸中消耗過多的流量/時間。

可是Websocket只須要一次HTTP握手,因此說整個通信過程是創建在一次鏈接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要查看identity info的信息。

時由客戶主動詢問,轉換爲服務器(推送)有信息的時候就發送(固然客戶端仍是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不須要佔用自己速度就慢的客服(Handler)了

——————–

至於怎麼在不支持Websocket的客戶端上使用Websocket。。答案是: 不能

可是能夠經過上面說的 long poll 和 ajax 輪詢 來 模擬出相似的效果

相關文章
相關標籤/搜索