咱們先看一下下面這張圖:前端
能夠看到這是一個簡易的聊天室,兩個窗口的消息是實時發送與接收的,這個主要就是用咱們今天要講的websocket實現的。java
websocket是一種網絡通訊協議,咱們都知道http協議,http協議只能從客戶端主動發起,不能從服務端推送數據到客戶端,今天咱們講的websocket就是一種不只能從客戶端發送數據到服務端,也能夠主動從服務的推送數據給客戶端的一種協議。
咱們先看一張圖:web
咱們能夠看到,http請求是客戶端發起請求,服務端響應,而後斷開鏈接,客戶端發起,服務端響應的一種循環。而websocket協議是客戶端發起鏈接後,就會一直保持鏈接,期間客戶端和服務端均可以向對方發送數據,直到鏈接關閉。
websocket其餘的一些特色:ajax
(1)創建在 TCP 協議之上,服務器端的實現比較容易。(2)與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器。sql
(3)數據格式比較輕量,性能開銷小,通訊高效。chrome
(4)能夠發送文本,也能夠發送二進制數據。跨域
(5)沒有同源限制,客戶端能夠與任意服務器通訊。瀏覽器
(6)協議標識符是
ws
(若是加密,則爲wss
),服務器網址就是 URL。服務器
試想一下這樣的場景,咱們須要實現一個支付成功後,向用戶給一個成功的提示,那麼在websocket協議沒有應用以前,人們是使用一種輪詢的方式。就是客戶端定時向服務端發送請求,看有沒有收到支付金額,沒有就一直髮送,收到了再中止。相似下面的代碼:websocket
function getIsPaySuccess() { var timmer = setInterval(function () { $.ajax({ url: '/getJayStatus', success: function (res) { if (res.status) { clearInterval(timmer) } }, fail: function () { } }) }, 1000) }
在發送請求的工程中,浪費了大量的資源,並且響應也不是及時的,由於我是每隔1秒請求一次,並不能馬上獲得支付成功的狀態。這時候咱們就須要用到websocket的方式了。整體來講,websocket須要用在一些能及時響應的場景中。
1. 社交訂閱
有時候咱們須要及時收到訂閱消息,好比說開獎通知,好比說在線邀請,支付結果等。
2. 多玩家遊戲
不少遊戲都是協同做戰的,玩家的操做和狀態確定須要及時同步到全部玩家。
3. 協同編輯文檔
同一份文檔,編輯狀態得同步到全部參與的用戶界面上。
4. 數據流狀態
好比說上傳下載文件,文件進度,文件是否上傳成功。
5. 多人聊天
不少場景下都須要多人蔘與討論聊天,用戶發送的消息得第一時間同步到全部用戶。
6. 股票虛擬貨幣價格
股票和虛擬貨幣的價格都是實時波動的,價格跟用戶的操做息息相關,及時推送對用戶跟盤有很大的幫助。
咱們用下面一段代碼來說解websocket的建立,擁有的屬性,能調用的方法和能監聽的事件:
// 鏈接狀態的枚舉 const readyStateMap = { 0: '鏈接還沒有創建', 1: '鏈接已創建,能夠進行通訊', 2: '鏈接正在進行關閉', 3: '鏈接已經關閉或者鏈接不能打開' } Object.freeze(readyStateMap) class WsTest { constructor(url) { // 建立websocket實例,第一個參數是鏈接的url,沒有跨域限制,第二個參數是可接受的協議 this.ws = new WebSocket(url); // readyState屬性,只讀屬性,表示鏈接狀態 console.log(this.ws.readyState, readyStateMap[this.ws.readyState]) // 只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數。 console.log(this.ws.bufferedAmount) this.initWs() } initWs() { // 事件onopen,指鏈接成功 this.ws.onopen = () => { console.log(this.ws.readyState, readyStateMap[this.ws.readyState]) // 方法,向服務端發送消息,傳輸字符串 this.ws.send(JSON.stringify({type: 'connection'})) }; // 事件onmessage,指接收到服務端消息 this.ws.onmessage = (evt) => { console.log(evt.data, 'data') const {type, msg} = JSON.parse(evt.data); console.log('消息類型:' + type, '用戶id:' + msg) // 方法,關閉鏈接 this.ws.close() console.log(this.ws.readyState, readyStateMap[this.ws.readyState]) }; // 事件onclose,關閉鏈接,也能夠從服務端強制斷開鏈接,這裏能夠從新發起鏈接 this.ws.onclose = () => { console.log(this.ws.readyState, readyStateMap[this.ws.readyState]) }; // 事件onerror,通訊發生錯誤時觸發 this.ws.onerror = () => { console.log(this.ws.readyState, readyStateMap[this.ws.readyState]) }; } } const ws = new WsTest('ws://203.195.156.57:30002')
上面的代碼都有註釋,應該不難看出websocket的使用方法,這段代碼能夠直接放到chrome控制檯運行:
兼容性
能夠看到幾乎全部瀏覽器都支持了。
總結
本文主要講了websocket協議的定義和基本用法,下一期我會結合本文開始的聊天室來實現一個具體的websocket應用。
聊天室在線體驗地址:關注公衆號:程序零世界 體驗在線聊天
學習如逆水行舟,不進則退,前端技術飛速發展,若是天天不堅持學習,就會跟不上,我會陪着你們,天天堅持推送博文,跟你們一同進步,但願你們能關注我,第一時間收到最新文章。