什麼是websocketjavascript
WebSocket是HTML5新增的協議,它的目的是在瀏覽器和服務器之間創建一個不受限的雙向通訊的通道,使服務器和客戶端能夠實時高效的通訊。同時服務器能夠在任意時刻主動發送消息給客戶端-瀏覽器。java
爲何會出現 websoket?node
爲何傳統的HTTP協議不能作到WebSocket實現的功能?web
咱們都知道HTTP 協議,在 HTTP1.0
中,一次req 請求對應一個 res,而後此次HTTP請求就結束了。npm
在HTTP1.1中進行了改進,增長了keep-alive,能夠對一個請求能夠進行重用,能夠進行屢次Request和Response。可是HTTP協議中永遠是一個request對應一個response。並且這個response也是被動的,不能主動發起。編程
這樣一來,要在瀏覽器中搞一個實時聊天,在線炒股(不鼓勵),或者在線多人遊戲的話就無法實現了,只能藉助Flash插件,輪詢,長鏈接。api
輪詢是指瀏覽器經過JavaScript啓動一個定時器,而後以固定的間隔給服務器發請求,詢問服務器有沒有新消息。這個機制的缺點一是實時性不夠,二是頻繁的請求會給服務器帶來極大的壓力。瀏覽器
Comet本質上也是輪詢,可是在沒有消息的狀況下,服務器先拖一段時間,等到有消息了再回復。這個機制暫時地解決了實時性問題,可是它帶來了新的問題:以多線程模式運行的服務器會讓大部分線程大部分時間都處於掛起狀態,極大地浪費服務器資源。另外,一個HTTP鏈接在長時間沒有數據傳輸的狀況下,鏈路上的任何一個網關均可能關閉這個鏈接,而網關是咱們不可控的,這就要求Comet鏈接必須按期發一些ping數據表示鏈接「正常工做」。安全
以上兩種機制都治標不治本,因此,HTML5推出了WebSocket標準,讓瀏覽器和服務器之間能夠創建無限制的全雙工通訊,任何一方均可以主動發消息給對方。服務器
在說下 HTTP是應用層協議,是創建在TCP協議之上的,TCP協議屬於傳輸層協議,自己就是可靠的,全雙工通訊協議,HTTP協議的請求-應答機制限制了全雙工通訊。當WebSocket鏈接創建之後,其實只是簡單規定了一下:說哥們,接下來,我們通訊就不使用HTTP那套了,我們儘可能保持連接,隨便互相發數據吧。
握手機制:
WebSocket並非全新的協議,而是利用了HTTP協議來創建鏈接。
瀏覽器和服務器只須要作一次握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。
具體的握手過程就不說了,會涉及到代碼,沒辦法說明。有興趣的能夠看下 mdn 上 瞭解下。
咱們來看看WebSocket鏈接是如何建立的。
首先,WebSocket鏈接必須由瀏覽器發起,由於請求協議是一個標準的HTTP請求,格式以下:
GET ws://localhost:3000/ws/chat HTTP/1.1 Host: localhost Upgrade: websocket Connection: Upgrade Origin: http://localhost:3000 Sec-WebSocket-Key: client-random-string Sec-WebSocket-Version: 13
該請求和普通的HTTP請求有幾點不一樣:
/path/
,而是以ws://
開頭的地址;Upgrade: websocket
和Connection: Upgrade
表示這個鏈接將要被轉換爲WebSocket鏈接;Sec-WebSocket-Key
是用於標識這個鏈接,並不是用於加密數據;Sec-WebSocket-Version
指定了WebSocket的協議版本。隨後,服務器若是接受該請求,就會返回以下響應:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: server-random-string
該響應代碼101
表示本次鏈接的HTTP協議即將被更改,更改後的協議就是Upgrade: websocket
指定的WebSocket協議。
版本號和子協議規定了雙方能理解的數據格式,以及是否支持壓縮等等。若是僅使用WebSocket的API,就不須要關心這些。
如今,一個WebSocket鏈接就創建成功,瀏覽器和服務器就能夠隨時主動發送消息給對方。消息有兩種,一種是文本,一種是二進制數據。一般,咱們能夠發送JSON格式的文本,這樣,在瀏覽器處理起來就十分容易。
爲何WebSocket鏈接能夠實現全雙工通訊而HTTP鏈接不行呢?實際上 dddd 安全的WebSocket鏈接機制和HTTPS相似。首先,瀏覽器用wss://xxx
建立WebSocket鏈接時,會先經過HTTPS建立安全的鏈接,而後,該HTTPS鏈接升級爲WebSocket鏈接,底層通訊走的仍然是安全的SSL/TLS協議。
瀏覽器支持狀況
很顯然,要支持WebSocket通訊,瀏覽器得支持這個協議,這樣才能發出ws://xxx
的請求。目前,支持WebSocket的主流瀏覽器以下:
服務器:
因爲WebSocket是一個協議,服務器具體怎麼實現,取決於所用編程語言和框架自己。Node.js自己支持的協議包括TCP協議和HTTP協議,要支持WebSocket協議,須要對Node.js提供的HTTPServer作額外的開發。已經有若干基於Node.js的穩定可靠的WebSocket實現,咱們直接用npm安裝使用便可。
node 裏 好比 有 ws,socket.io 模塊,npm 裝就能夠.
使用相關
Websocket 使用 ws 或 wss 的統一資源標誌符,相似於 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。如:
ws://example.com/wsapi wss://secure.example.com/
Websocket 使用和 HTTP 相同的 TCP 端口,能夠繞過大多數防火牆的限制。默認狀況下,Websocket 協議使用 80 端口;運行在 TLS 之上時,默認使用 443 端口。
如何使用
能夠參考 mdn 的 api 文檔便可
總結:
websocket 就是一個基於 http 的一個加強的協議,既然是協議 瀏覽器和服務器都須要支持了這個協議才能提供咱們使用。在這個基礎上咱們只須要使用已提供的 api 便可實現咱們的需求。
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。
HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。
參考資料 https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
我寫的 demo:
使用 websocket 作了一個熱更新 demo,有興趣能夠看下