隨着Web
領域的飛速發展,最初設計得十分簡單的HTTP
協議在當今的應用上顯得捉襟見肘,協議的瓶頸也逐漸顯露出來。web
「既然HTTP
這麼爛?爲何咱們不拋棄它再設計一個全新的協議,而是要給他打補丁呢?」這是某次我和我舍友在宿舍喝着小酒,探討SpringMVC
時談到的一個話題。spring
最初的HTTP
,只是想把HTTP
看成傳輸HTML
文檔的協議,設計者沒有想到HTTP
經久不衰,須要承受愈來愈複雜的業務職責。瀏覽器
因此HTTP
的設計無可厚非,只是它不「那麼地」適應這個時代了。可是目前基於HTTP
協議實現的Web
瀏覽器遍及全球,並不能隨意動搖HTTP
的地位。服務器
因此爲了知足現代社會日益增加的業務需求,涌現出無數企圖「消除」HTTP
瓶頸的解決方案,其中的一項就是——「WebSocket
」。微信
爲何會出現WebSocket
協議呢?websocket
假設咱們去實現相似微信同樣的網頁在線聊天工具,咱們要解決什麼問題呢?網絡
很顯然,消息推送是當前業務場景下的一個技術瓶頸。異步
當前帳號收到了消息,咱們怎麼在網頁裏「實時地」獲取到消息並顯示呢?注意要保障在線聊天的實時性。socket
能實現嗎?顯然不能。spring-boot
瀏覽器向客戶端發起HTTP
請求,請求到含有當前消息的HTML
文件,渲染給用戶。請求結束,不考慮持久鏈接的狀況下,斷開TCP
鏈接。
當服務器有新消息時,除非用戶當前網頁刷新,不然在只使用HTTP
的狀況下沒法實現實時性。
Ajax
意思就是用JavaScript
執行異步網絡請求。
——《廖雪峯的JavaScript
教程》
使用Ajax
,能夠在瀏覽器內用JavaScript
「偷偷」地發起網絡請求,查詢最新的消息,下降操做成本,提高用戶體驗。
爲了保證明時性,須要前臺定時發送Ajax
請求。例如:每5s
發送一次網絡請求查詢消息,將數據的延時性保持在固定間隔之內。
缺點很明顯,會產生大量的HTTP
請求,若是消息長時間沒有更新,十分浪費通訊資源。
爲了不產生大量無用的HTTP
請求,產生了Comet
。
Ajax
發起查詢消息的請求,服務器接收到該消息,不會當即響應,Comet
會將響應置於掛起狀態,當服務器端有內容更新時,再返回響應。
與方案二相比,減小了無用的HTTP
請求,同時也保證了數據的實時性。
缺點就是服務器壓力過大,服務器爲了保持掛起的HTTP
響應,會消耗更多的寶貴的服務器資源。
由於HTTP
是請求響應模式,因此若是是基於HTTP
實現實時性,過於複雜。請求都是客戶端發起的,客戶端怎麼知道服務器的內容何時更新呢?
因此,2011年12月11日
,RFC 6455 - The WebSocket Protocol
標準被確立。
WebSocket
,一樣基於TCP
協議,是Web
瀏覽器與Web
服務器之間的全雙工通訊標準。
若是有數據更新,服務器能夠向客戶端發送數據,使實現實時性變得簡單。
WebSocket
鏈接的創建須要握手,說是握手,其實也是爲了兼容HTTP
瀏覽器的一種手段。
客戶端向服務器發送HTTP
數據包,請求創建握手。
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: xxxxxxxxxx Sec-WebSocket-Version: 13
具體的細節我就不描述了,本身去查閱文檔。
客戶端發送HTTP
請求,首部Upgrade: websocket
,表示客戶端但願將通訊協議從HTTP
升級爲WebSocket
協議。
服務器返回響應,贊成切換協議。
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xxxxxxxxxx
HTTP
響應狀態碼101
,切換協議。
握手以後即創建起了鏈接,開始全雙工通訊。
WebSocket
與HTTP
協議相似,其資源地址相似:ws://server.example.com:8080/path
。
本文共同討論了WebSocket
協議的一些理論基礎,夜深了,先寫到這裏。
下一篇文章,使用spring-boot
實現簡易的WebSocket
示例。