1.開(kāi)篇
以下為我之前給組內(nèi)分享的有關(guān)WebSocket的話題,略有刪減糕簿,未完待續(xù)探入。。懂诗。
001
長(zhǎng)期以來(lái)蜂嗽,在web領(lǐng)域中,若想讓客戶端與服務(wù)端交互殃恒,我們首(或者說(shuō)唯一的)選的肯定是Http植旧。而隨著web應(yīng)用的快速發(fā)展,數(shù)據(jù)的消費(fèi)量和功能需求的強(qiáng)度也逐漸增加离唐,很顯然病附,傳統(tǒng)的Http模式早已不能滿足我們,更多的需求則希望服務(wù)端可以“主動(dòng)”跟客戶端通信來(lái)增加交互亥鬓。不得已完沪,long-polling逐漸的被實(shí)現(xiàn)在服務(wù)端,而這仍然是一種十分被動(dòng)的策略嵌戈。
002
傳統(tǒng)的Http很簡(jiǎn)單:客戶端主動(dòng)發(fā)起請(qǐng)求覆积,服務(wù)端接收到請(qǐng)求后立刻返回結(jié)果,一次“單向且即時(shí)的交流”就此完成熟呛。
003
那么問(wèn)題來(lái)了:如果客戶端不請(qǐng)求宽档,又想從服務(wù)端獲取信息,那該怎么辦呢庵朝?
試想下以下場(chǎng)景:
1.你的好友發(fā)了條Facebook吗冤,你想回復(fù)些什么又厉,正當(dāng)你typing的時(shí)候,發(fā)現(xiàn)突然多個(gè)一個(gè)“贊”椎瘟,如果你僥幸利用Network記錄了此過(guò)程覆致,你會(huì)詫異的發(fā)現(xiàn),并沒(méi)有什么請(qǐng)求發(fā)送肺蔚,那么這個(gè)“贊”又是如何更新到你的頁(yè)面的呢篷朵?
2.你修復(fù)了一個(gè)bug,git操作行云流水婆排,提交代碼后觸發(fā)了流水線,你倒杯茶靜靜的等待部署的結(jié)果笔链,lint-->build-->test-->deploy段只,這一連串的狀態(tài)更新與你無(wú)關(guān),它就像一個(gè)信號(hào)接收器一樣一直接收著來(lái)后端的信息鉴扫,這又是如何做到的呢赞枕?
其實(shí)web交互還有一些其他方式,下面的一些介紹坪创,也許會(huì)讓你對(duì)上面的疑問(wèn)有所解答炕婶。
004
Polling Request其實(shí)也是Http請(qǐng)求,它不停的循環(huán)莱预,使得在一些場(chǎng)景下柠掂,讓用戶誤以為它是“一直”在那里工作:譬如如果對(duì)準(zhǔn)確度要求不高,一些進(jìn)度條或者loading狀態(tài)的更新就可以采用這種辦法依沮,因?yàn)橛脩粼谝獾牟皇菧?zhǔn)確度涯贞,而是“它是否在工作”,以此來(lái)增強(qiáng)體驗(yàn)危喉。但大部分情況下宋渔,它都是傻瓜式的,輪訓(xùn)的時(shí)間段和處理邏輯的時(shí)間一旦沖突辜限,結(jié)果往往很難預(yù)料皇拣。
005
Long-Polling Request最大的差別是在于當(dāng)客戶端將請(qǐng)求發(fā)給服務(wù)端后,服務(wù)端并沒(méi)有立刻返回薄嫡,而是一直持有著這次交互氧急,一直等到服務(wù)端真正的獲取到信息之后,才會(huì)將結(jié)果返回給客戶端岂座。因此從表象看來(lái)态蒂,似乎客戶端已經(jīng)發(fā)送了請(qǐng)求,而頁(yè)面沒(méi)有立刻更新费什,那就代表結(jié)果為空钾恢,以為這次請(qǐng)求交互已經(jīng)結(jié)束手素,而過(guò)一會(huì),突然又更新了瘩蚪,“感覺(jué)”像是服務(wù)端主動(dòng)推送了數(shù)據(jù)泉懦,而實(shí)際上只是一次“延遲”的交互。
006
EventSource顧名思義疹瘦,在客戶端與服務(wù)端交互的過(guò)程中崩哩,是以事件進(jìn)行傳遞的,更確切的說(shuō)言沐,它是單向的邓嘹,但它和傳統(tǒng)Http恰好相反∠找龋客戶端和服務(wù)端一旦建立起鏈接汹押,事件只能由服務(wù)端向客戶端推送。不難看出起便,它非常適用于客戶端需要被動(dòng)實(shí)時(shí)頻繁更新信息的交互場(chǎng)景棚贾。如果你利用Network來(lái)調(diào)試,也是能夠清晰的看到event stream的榆综。
007
可有沒(méi)有什么辦法可以既可以讓客戶端從服務(wù)端獲取信息妙痹,且反之亦然呢?
008
不賣(mài)關(guān)子了鼻疮,主角登場(chǎng):WebSocket
與Http不同怯伊,WebSocket可以在沒(méi)有客戶端請(qǐng)求的情況下讓服務(wù)端主動(dòng)給客戶端發(fā)送數(shù)據(jù),客戶端和服務(wù)端可以實(shí)時(shí)地進(jìn)行雙向通信陋守,因此它非常適合“即時(shí)在線”的溝通震贵。
而在通信安全方面,WebSocket有著自己獨(dú)立的加密協(xié)議wss://
水评,與Http類(lèi)似猩系,ws://
并不被推薦,原因不言自明中燥。
WebSocket的使用也十分簡(jiǎn)單寇甸,客戶端建立鏈接如下:
const url = 'wss://myserver.com/something'
const connection = new WebSocket(url)
此時(shí)便可以訂閱相關(guān)事件:
connection.onopen = () => {}
connection.onerror = error => {}
009
用之前呢,我們還是最好看一下can I use
010
WebSocket的服務(wù)端實(shí)現(xiàn)的版本非常多疗涉,以Node.js為例拿霉,代碼片段如下:
npm i ws
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })
wss.on('connection', ws => {
ws.on('message', message => {
console.log(`Received message => ${message}`)
})
ws.send('hello world!')
})
011
如果你有嘗試以上介紹做點(diǎn)小demo的話,你會(huì)發(fā)現(xiàn)咱扣,利用Network是可以看到所有明文的信息的绽淘,這種“暴露性”可能讓你感到不安。而如果你又很好奇的去看看某彈幕平臺(tái)的WebSocket信息闹伪,你會(huì)發(fā)現(xiàn)完全是加密沪铭,這一點(diǎn)和傳統(tǒng)的Socket通信也是類(lèi)似的植锉,這些信息其實(shí)都是經(jīng)過(guò)了某些算法進(jìn)行二進(jìn)制化岖瑰,但其實(shí)都是有固定的格式和校驗(yàn)碼的腿堤。
012
帶著這點(diǎn)好奇心腕唧,留下最后一個(gè)問(wèn)題:如何獲取到某直播平臺(tái)的彈幕(使用WebSocket)數(shù)據(jù)包呢?且如果WebSocket的信息又被二進(jìn)制化(或者加密)了呢赔退?
013
To be continued...