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輪詢的原理很是簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。併發
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 輪詢
來 模擬出相似的效果