八問WebSocket協議:爲你快速解答WebSocket熱門疑問

1、引言

WebSocket是一種比較新的協議,它是伴隨着html5規範而生的,雖然還比較年輕,但大多主流瀏覽器都已經支持。它使用方面、應用普遍,已經滲透到先後端開發的各類場景中。javascript

對http一問一答中二式流程(就是從所周之的「長輪詢」技要啦)的不滿,催生了支持雙向通訊的WebSocket誕生。WebSocket是個不太乾淨協議。php

本文將從8個常見的疑問入手,爲還不瞭解WebSocket協議的開發者快速普及相關知識,從而節省您學習WebSocket的時間。html

另外,若是您對Web端的即時通信技術還徹底不瞭解,那麼《新手入門貼:詳解Web端即時通信技術的原理》、《Web端即時通信技術盤點:短輪詢、Comet、Websocket、SSE》這兩篇文章請您務必抽時間讀一讀。html5

學習交流:java

  • 即時通信/推送技術開發交流4羣:101279154[推薦]
  • 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》

(本文同步發佈於:http://www.52im.net/thread-24...nginx

2、參考文章

《WebSocket詳解(一):初步認識WebSocket技術》web

《WebSocket詳解(二):技術原理、代碼演示和應用案例》chrome

《WebSocket詳解(三):深刻WebSocket通訊協議細節》編程

《WebSocket詳解(四):刨根問底HTTP與WebSocket的關係(上篇)》小程序

《WebSocket詳解(五):刨根問底HTTP與WebSocket的關係(下篇)》

《WebSocket詳解(六):刨根問底WebSocket與Socket的關係》

《理論聯繫實際:從零理解WebSocket的通訊原理、協議格式、安全性》

3、更多資料

Web端即時通信新手入門貼:

《新手入門貼:詳解Web端即時通信技術的原理》

Web端即時通信技術盤點請參見:

《Web端即時通信技術盤點:短輪詢、Comet、Websocket、SSE》

關於Ajax短輪詢:

找這方面的資料沒什麼意義,除非忽悠客戶,不然請考慮其它3種方案便可。

有關Comet技術的詳細介紹請參見:

《Comet技術詳解:基於HTTP長鏈接的Web端實時通訊技術》

《WEB端即時通信:HTTP長鏈接、長輪詢(long polling)詳解》

《WEB端即時通信:不用WebSocket也同樣能搞定消息的即時性》

《開源Comet服務器iComet:支持百萬併發的Web端即時通信方案》

更多WebSocket的詳細介紹請參見:

《新手快速入門:WebSocket簡明教程》

《Socket.IO介紹:支持WebSocket、用於WEB端的即時通信的框架》

《socket.io和websocket 之間是什麼關係?有什麼區別?》

有關SSE的詳細介紹文章請參見:

《SSE技術詳解:一種全新的HTML5服務器推送事件技術》

更多WEB端即時通信文章請見:

http://www.52im.net/forum.php...

4、1問WebSocket:WebSocket協議只能瀏覽器發起麼?

不是。目前此協議的受衆的也不只僅是web開發者。

WebSocket只是一種協議,它和http協議同樣,使用相似okhttp的組件,能夠在任何地方進行調用,甚至能夠藉助WebSocket實現RPC框架。

5、2問WebSocket:WebSocket和HTTP什麼關係?

WebSocket和http同樣,都是處於OSI模型中的最高層:應用層。

WebSocket藉助http協議進行握手,握手成功後,就會變身爲TCP通道,今後與http再也不相見。

使用netstat或者ss,可以看到對應的鏈接,它與處於抽象層的socket,在外觀上沒有區別。

更多WebSocket和HTTP的關係,以及與Socket的區別,可進一步閱讀如下文章:

《WebSocket詳解(四):刨根問底HTTP與WebSocket的關係(上篇)》

《WebSocket詳解(五):刨根問底HTTP與WebSocket的關係(下篇)》

《WebSocket詳解(六):刨根問底WebSocket與Socket的關係》

6、3問WebSocket:WebSocket和長輪詢有什麼區別?

長輪詢,就是客戶端發送一個請求,服務端將一直在這個鏈接上等待(固然有一個超長的超時時間),直到有數據才返回,它依然是一個一問一答的模式。好比著名的comted。

WebSocket在握手成功後,就是全雙工的TCP通道,數據能夠主動從服務端發送到客戶端,處於連接兩端的應用沒有任何區別。

WebSocket建立的鏈接和Http的長鏈接是不同的。因爲Http長鏈接底層依然是Http協議,因此它仍是一問一答,只是Hold住了一條命長點的鏈接而已。

長輪詢和Http長鏈接是阻塞的I/O,但WebSocket能夠是非阻塞的(具體是多路複用)。

這方面更深刻的資料,請進一步學習:

《Comet技術詳解:基於HTTP長鏈接的Web端實時通訊技術》

《WEB端即時通信:HTTP長鏈接、長輪詢(long polling)詳解》

7、4問WebSocket:如何建立一個WebSocket鏈接?

WebSocket的鏈接建立是藉助Http協議進行的。這樣設計主要是考慮兼容性,在瀏覽器中就能夠很方便的發起請求,看起來比較具備迷惑性。

下圖是一個典型的由瀏覽器發起的ws請求,能夠看到和http請求長的是很是類似的。

可是,它只是請求階段長得像而已:
圖片描述

請求的地址,通常是:ws://***,或者是使用了SSL/TLS加密的安全協議wss:,用來標識是WebSocket請求。

1)首先,經過Http頭裏面的Upgrade域,請求進行協議轉換。若是服務端支持的話,就能夠切換到WebSocket協議。簡單點講:鏈接已經在那了,經過握手切換成ws協議,就是切換了鏈接的一個狀態而已。

2)Connection域能夠認爲是與Upgrade域配對的頭信息。像nginx等代理服務器,是要先處理Connection,而後再發起協議轉換的。

3)Sec-WebSocket-Key 是隨機的字符串,服務器端會用這些數據來構造出一個 SHA-1 的信息摘要。如此操做,能夠儘可能避免普通 HTTP 請求被誤認爲 WebSocket 協議。

其餘的,像Sec-WebSocket*字樣的頭信息,代表了客戶端支持的子協議以及其餘信息。像loT中很流行的mqtt,就能夠做爲WebSocket的子協議。

使用javascript,能夠很容易鏈接一個WebSocket服務端:

<script>

varws = newWebSocket('ws://localhost:80');

ws.onopen = function() {

console.log('ws onopen');

ws.send('from client: hello');

};

ws.onmessage = function(e) {

console.log('ws onmessage');

console.log('from server: '+ e.data);

};

...

</script>

更詳細的資料,請閱讀:《WebSocket詳解(三):深刻WebSocket通訊協議細節》。

8、5問WebSocket:WebSocket如何處理數據?

WebSocket是經過事件通知的方式運行的。它包含四個事件和兩個動做(發送和關閉)。

WebSocket的事件:
圖片描述

數據可直接經過Socket.send()方法進行傳輸。

經過chrome的Inspect->Network->WS,能夠看到頁面上的WebSocket鏈接。

如圖Opcode爲2,代表它是一個二進制幀:

WebSocket有相似tcp協議的幀格式,在此不作過多解釋。(能夠詳細閱讀:《理論聯繫實際:從零理解WebSocket的通訊原理、協議格式、安全性》)

參考:https://tools.ietf.org/html/r...

9、6問WebSocket:如何使用Nginx作WebSocket的負載均衡?

nginx官網已經給出了例子。主要是Upgrade和Connection頭的設置。

Nginx的中的配置以下:

map $http_upgrade $connection_upgrade {

default upgrade;

''close;

}

location /chat/{

proxy_pass http://backend;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection $connection_upgrade;

}

須要注意的是,nginx作負載均衡,不須要配置ip_hash等參數,nginx自然支持。因爲ip_hash僅使用ip地址的前三個數字作hash,還有可能形成服務端的不均衡。

特別注意:

在IM聊天系統場景下,Nginx提供給WebSocket的這種所謂的「負載均衡」,只能解決傳統分佈系統中的SLB服務器要作的事。

通俗地說,Nginx只能幫助完成引導WebSocket客戶鏈接到哪個WebSocket服務端實例,在IM集羣狀況下,若是兩個用戶處於不一樣的WebSocket實例下時,它們之間的跨實例通訊,Nginx是沒有辦法實現的,這一塊的邏輯仍是得IM開發者自已來實現。

總而言之,Nginx提供給WebSocket的所謂「負載均衡」,並非IM開發者認爲的那種全功能集羣!

10、7問WebSocket:Java服務端怎麼實現WebSocket?

可使用javax.WebSocket下的包,簡單的實現ws服務端。目前基本能夠經過註解的方式去編寫代碼,好比ServerEndpoint。

推薦使用基於netty的netty-socketio進行服務端的編寫。因爲使用的是netty,因此可以在多個層面進行切入,獲取一些統計數據,執行一些控制指令。socketio是一套解決方案,它有多個語言的客戶端,並處理了市面上大多數的兼容問題。

友情忠告:socket.io幾乎是市面上最好的開源WebSocket解決方案,但netty-socketio這個開源工程並不是socket.io官方團隊維護,而對於socket.io這個版本帝來講,其餘的非官方版本能不能即時跟進,也是一個須要考慮的風險因素。

11、8問WebSocket:WebSocket能幹些啥?

1)通知功能:

保持一個長鏈接,當服務端遊新的消息,可以實時的推送到使用方。像知乎的點贊通知、評論等,均可以使用WebSocket通訊。

某些使用H5的客戶端,爲了簡化開發,也會使用WebSocket進行消息的通知,因爲它是實時推送的,會有更好的用戶體驗。

2)數據收集:

一些次優級別的數據,好比行爲日誌、trace、異常執棧收集等,均可以開闢專門的WebSocket通道進行傳輸。這可以增長信息的集中度,並能及時的針對用戶的行爲進行合適的配置推送。因爲大多數瀏覽器內核都支持,它將使客戶端APM編程模型變得簡單。

3)加密 && 認證:

雖然使用Fiddler、Charles等可以抓到不少WebSocket包。但若是同時開啓SSL,傳輸加密後的二進制數據,會大幅增長破解的成本,會安全的多。

4)反向控制鉤子:

這個...因爲是雙工長鏈接,服務端徹底能夠推送一些鉤子命令,甚至直接是代碼,在客戶端進行執行。好比截個屏,錄個音,種個小馬。用戶只要經過了受權申請,剩下的就隨你發揮了。

支付寶偷偷調用你的相機給你拍照的梗,我是相信的。

十二:本文小結

想當年,cometd的出現,驚爲天人,振奮了好久。但技術突飛猛進,cometd已經衰老,而Socket.io獲得了快速發展。WebSocket通過一段時間的混沌期,規範已經愈來愈完善,使用也愈來愈方便,不須要再處理那麼多的兼容。

但它的本質,仍是新瓶裝舊酒,換湯不換藥。WebSocket的發展得益於HTML5規範的制定。規範的意義,就是約束廠商們天馬行空的實現,以及指明發展的方向。

這固然有典型的反例,那就是ie。如今,只有一羣公認的**,還堅持在用。

附錄:更多WEB端即時通信資料

《新手入門貼:史上最全Web端即時通信技術原理詳解》

《Web端即時通信技術盤點:短輪詢、Comet、Websocket、SSE》

《SSE技術詳解:一種全新的HTML5服務器推送事件技術》

《Comet技術詳解:基於HTTP長鏈接的Web端實時通訊技術》

《新手快速入門:WebSocket簡明教程》

《WebSocket詳解(一):初步認識WebSocket技術》

《WebSocket詳解(二):技術原理、代碼演示和應用案例》

《WebSocket詳解(三):深刻WebSocket通訊協議細節》

《WebSocket詳解(四):刨根問底HTTP與WebSocket的關係(上篇)》

《WebSocket詳解(五):刨根問底HTTP與WebSocket的關係(下篇)》

《WebSocket詳解(六):刨根問底WebSocket與Socket的關係》

《socket.io實現消息推送的一點實踐及思路》

《LinkedIn的Web端即時通信實踐:實現單機幾十萬條長鏈接》

《Web端即時通信技術的發展與WebSocket、Socket.io的技術實踐》

《Web端即時通信安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)》

《開源框架Pomelo實踐:搭建Web端高性能分佈式IM聊天服務器》

《使用WebSocket和SSE技術實現Web端消息推送》

《詳解Web端通訊方式的演進:從Ajax、JSONP 到 SSE、Websocket》

《MobileIMSDK-Web的網絡層框架爲什麼使用的是Socket.io而不是Netty?》

《理論聯繫實際:從零理解WebSocket的通訊原理、協議格式、安全性》

《微信小程序中如何使用WebSocket實現長鏈接(含完整源碼)》

《八問WebSocket協議:爲你快速解答WebSocket熱門疑問》

(本文同步發佈於:http://www.52im.net/thread-24...

相關文章
相關標籤/搜索