WebSocket協(xié)議可以為網(wǎng)站和應(yīng)用提供真正的雙向通信,具有控制開銷、保持連接狀態(tài)、更強(qiáng)實時性、更好的壓縮效果等優(yōu)點,是當(dāng)下低延時應(yīng)用最常采用的一種技術(shù)協(xié)議。
websocket作為用于雙向通信的實用協(xié)議,在筆者最近做的全平臺私信系統(tǒng)進(jìn)行了應(yīng)用。本次開發(fā)的私信系統(tǒng)與普遍理解的“發(fā)送-接受-發(fā)送”三個流程分開不一樣,實現(xiàn)的是類似于QQ與微信的實時通信系統(tǒng),需要做到收發(fā)消息實時化。
進(jìn)行通信協(xié)議選定的時候,不能由服務(wù)器主動聯(lián)系客戶端,又因為每次通信都需要經(jīng)過握手請求、響應(yīng)步驟進(jìn)行連接重建的http協(xié)議只能通過輪詢進(jìn)行偽雙向通信,所以http協(xié)議首先被我們排除了,在HTML5下的協(xié)議websocket映入了我們的眼簾。
WebSocket能更好的節(jié)省服務(wù)器資源和帶寬,并且能夠更實時地進(jìn)行通訊,它的優(yōu)勢:
? 較少的控制開銷。在連接創(chuàng)建后,服務(wù)器和客戶端之間交換數(shù)據(jù)時,用于協(xié)議控制的數(shù)據(jù)包頭部相對較小。
? 更強(qiáng)的實時性。由于協(xié)議是全雙工的,所以服務(wù)器可以隨時主動給客戶端下發(fā)數(shù)據(jù)。相對于HTTP請求需要等待客戶端發(fā)起請求服務(wù)端才能響應(yīng),延遲明顯更少;即使是和Comet等類似的長輪詢比較,其也能在短時間內(nèi)更多次地傳遞數(shù)據(jù)。
? 保持連接狀態(tài)。與HTTP不同的是,Websocket需要先創(chuàng)建連接,這就使得其成為一種有狀態(tài)的協(xié)議,之后通信時可以省略部分狀態(tài)信息。而HTTP請求可能需要在每個請求都攜帶狀態(tài)信息(如身份認(rèn)證等)。
? 更好的二進(jìn)制支持。Websocket定義了二進(jìn)制幀,相對HTTP,可以更輕松地處理二進(jìn)制內(nèi)容。
? 可以支持?jǐn)U展。Websocket定義了擴(kuò)展,用戶可以擴(kuò)展協(xié)議、實現(xiàn)部分自定義的子協(xié)議。
? 更好的壓縮效果。相對于HTTP壓縮,Websocket在適當(dāng)?shù)臄U(kuò)展支持下,可以沿用之前內(nèi)容的上下文,在傳遞類似的數(shù)據(jù)時,可以顯著地提高壓縮率。
一、 在線聊天速度慢,斷開連接較快,不能更好的保持業(yè)務(wù)通訊
二、 網(wǎng)頁通訊信息更安全,連接更穩(wěn)定
三、 提供更高效的網(wǎng)頁通訊
四、 網(wǎng)絡(luò)抖動帶來的連接時斷時續(xù)問題
五、 訪問打不開網(wǎng)頁,需要刷新頁面
六、 同時在線人數(shù)多,如何實時推送所有用戶
七、 服務(wù)端支持WebSocket協(xié)議
八、 如何降低帶寬,保證成本
總之,如果你的應(yīng)用需要提供多個用戶相互交流,或者展示服務(wù)器端經(jīng)常變動的數(shù)據(jù),就十分需要使用WebSocket技術(shù)。
首先要明確的一點是,支持websocket協(xié)議的客戶端和服務(wù)器能夠使用websocket協(xié)議進(jìn)行雙向通信,也就是客戶端可以隨時向服務(wù)器發(fā)送請求,服務(wù)器也能夠隨時向客戶端發(fā)送請求。
跟http使用輪詢實現(xiàn)不一樣的是websocket一次連接成功后則可以重復(fù)進(jìn)行請求和響應(yīng),更好地節(jié)省了服務(wù)器的資源與帶寬。
websocket與http協(xié)議類似的是同樣建立于tcp傳輸協(xié)議之上,通過tcp傳輸層進(jìn)行數(shù)據(jù)傳輸。而客戶端與服務(wù)器端一般使用的通信協(xié)議仍是http,我們要使用websocket協(xié)議進(jìn)行通信則首先要建立起websocket連接,這個連接的建立依賴于http。
一個websocket連接首先發(fā)送http請求到服務(wù)器,注意比起平常的http請求多了4個字段,sec-WebSocket-* 為建立websocket協(xié)議的參數(shù),upgrade字段才是重點,告訴服務(wù)器我這次的請求不是單純的http請求,而是要求服務(wù)器升級連接并建立起websocket長連接。
服務(wù)器響應(yīng)也根據(jù)特殊的請求頭進(jìn)行了特殊響應(yīng),首先101返回碼表明本次連接的通信協(xié)議經(jīng)過了轉(zhuǎn)換并成功握手成功建立起了通信。connection字段和upgrade字段則表明本次通信協(xié)議進(jìn)行了升級轉(zhuǎn)換,轉(zhuǎn)換的是websocket協(xié)議。
websocket的協(xié)議標(biāo)識符為ws,從下圖Request URL看到本次websocket連接的協(xié)議標(biāo)識符為wws,這表示websocket連接是經(jīng)過加密處理的。
建立了websocket連接后,只要客戶端和服務(wù)器端任意一端不主動斷開連接前,通信行為都是在一個持久連接上發(fā)起,后續(xù)數(shù)據(jù)與請求都通過幀序列的形式進(jìn)行傳輸。
從chrome控制臺的Websocket調(diào)試面板中可以看到,在一個websocket連接中多次請求都可以由服務(wù)器進(jìn)行實時響應(yīng),實行實時上下行通信的能力得以見證。
通過WebSocket構(gòu)造函數(shù)可以創(chuàng)建websocket連接并返回提供管理該連接API的實例對象。
const ws = new WebSocket('wws://url');事件&屬性 | 定義 |
|---|---|
onopen | 服務(wù)器端響應(yīng)連接請求后,readyState狀態(tài)置為OPEN時觸發(fā)。標(biāo)志著握手階段已結(jié)束,可以進(jìn)行收發(fā)消息。 |
onmessage | 服務(wù)器端有消息到達(dá)時觸發(fā),可以接受文本和二進(jìn)制數(shù)據(jù)。 |
onclose | 連接關(guān)閉時,readyState狀態(tài)置為CLOSED時觸發(fā)。標(biāo)志著服務(wù)器端與客戶端不能再通信。 |
onerror | 錯誤發(fā)生時觸發(fā),會導(dǎo)致連接關(guān)閉。 |
readyState | websocket連接狀態(tài)。CONNECTING(連接中) OPEN(連接成功) CLOSING(關(guān)閉中) CLOSED(已關(guān)閉) |
protocol | websocket連接協(xié)議。ws & wws |
bufferedAmount | 調(diào)用send方法后在發(fā)送隊列緩存中的數(shù)據(jù)量,所有消息已發(fā)出則清零。 |
binaryType | 當(dāng)收到二進(jìn)制數(shù)據(jù)時,用于表示該二進(jìn)制數(shù)據(jù)的類型(blob & arraybuffer) |
// 監(jiān)聽到open事件后,向服務(wù)器發(fā)送success文本。ws.addEventListener('open', (e) => {
ws.send('success!');})(1) send 方法
// 文本數(shù)據(jù)const text = 'i am text';// 二進(jìn)制數(shù)據(jù)const blob = new Blob('i am blob');ws.send(text);ws.send(blob);(2) close 方法
close方法可以傳入兩個參數(shù) code 和 reason ,用于向服務(wù)器端說明關(guān)閉連接原因。
ws.close(1000, 'mission finished');// 不傳任何參數(shù),默認(rèn)code是1000,表示正常關(guān)閉ws.close();
在需要實現(xiàn)雙向?qū)崟r通信的場景下,不妨直接使用websocket協(xié)議吧。但是目前IE8和IE9是不支持websocket的,要實現(xiàn)該功能還是只能通過http 的long polling 方式去實現(xiàn)。
以上是websocket的基礎(chǔ)理論,希望了解后有助于大家的實踐!
掃碼贊賞,鼓勵支持
相關(guān)問題
Centos 7.x 下做端口映射/端口轉(zhuǎn)發(fā)Windows server 2008/2012/2016/2019 服務(wù)器桌面不顯示我的電腦(計算機(jī))的解決方案No input file specified的解決方法網(wǎng)站如何添加工信部網(wǎng)站備案號和鏈接代碼騰訊云對象存儲內(nèi)網(wǎng)與外網(wǎng)地址訪問Windows遠(yuǎn)程桌面多個用戶如何同時使用Chrome谷歌瀏覽器?