勿以惡小而爲之,勿以善小而不爲--------------------------劉備
勸諸君,多行善事積福報,莫作惡
一. 爲什麼需要 WebSocket?
在開發的過程中,如開發聊天室,或者客服聊天系統時,常常有新的客戶端(用戶)連接進來,也有老的客戶端(用戶)退出,
客戶端A進行羣發消息,其他的客戶端進行展示客戶端A發送的消息,
採用Http 協議進行處理時,需要在客戶端發送一個請求,然後服務器進行響應數據,客戶端拿着服務器響應過來的數據,
進行處理,最後展示處理好的數據。 請求是單向的,如果不發送請求,就不能獲取數據。
爲了更快,更準確地顯示消息,我們常常採用輪詢的方式,從服務器獲取數據。
輪詢方式指的是在JS客戶端編寫定時程序,每隔固定的一段時間往服務器發送請求,詢問服務器是否有新消息。
如 每隔10s,採用ajax的方式,往服務器發送一條請求,獲取服務器新的消息。
這種方式,實時性不夠,另外,頻繁地請求,也會給服務器造成巨大的壓力。
我們希望,有一種新的模式,不僅僅是客戶端請求服務器端的響應數據,也可以讓服務器端自動推送最新的消息。
當有新的用戶連接進來時(服務器最先知道客戶端連接進來了),服務器自動把這個新連接用戶連接進來的消息,推送給客戶端,
即 服務器告訴客戶端,“Xxx連接進來了”。
當有老的用戶退出時,服務器自動把這個消息推送給客戶端,即服務器告訴客戶端,“Xxx退出了”。
當客戶端A發送消息之後,服務器自動把這個消息推送給其他的客戶端, 即服務器告訴客戶端,“Xxx 發送了一條新消息: Xxx發送的消息內容”。
這樣,實時性會顯著地提升,而且也會減輕服務器的壓力。(以前,每隔10s,不管有沒有用戶的狀態發生改變,都會進行請求,現在,如果用戶的狀態沒有改變,服務器就不進行處理。 1分鐘用戶狀態沒有改變,那麼這一分鐘服務器就不進行任何操作,10分鐘用戶狀態不改變,那麼這10分鐘服務器就不進行任何操作)
這樣的技術,叫做 WebSocket。
WebSocket 於2011年被IETF定爲標準RFC 6455, 是在 Html5 時出現的一種新的標準,允許服務器向客戶端推送數據。
在WebSocket裏,瀏覽器和服務器只需要一次握手,就可以創建持久性連接,並且允許雙向傳輸數據。
二. WebSocket 的 API
二.一 WebSocket 的協議地址寫法
以前 Http的協議是, http://example.com:80/context/path
加密之後的,是 https://example.com:80/context/path
WebSocket 協議是, ws://example.com:80/context/path, ws 是 websocket的簡寫。
也可以進行加密, wss://example.com:80/context/path
加密和不加密的區別:
二.二 創建 WebSocket 對象
var webSocket=new WebSocket(ws協議的url);
如 創建 本地 ip地址的 WebSocket對象
var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat");
WebSocket 對象,需要瀏覽器的支持
- Chrome
- Firefox
- IE >= 10
- Sarafi >= 6
- Android >= 4.4
- iOS >= 8
建議使用 Chrome 和 Firefox 瀏覽器 。
二.三 WebSocket 的狀態值 readyState
WebSocket對象,有一個屬性 readyState, 該屬性有四個值,0,1,2,3 代表不同的狀態。
狀態值 | 意義 |
---|---|
0 | 連接尚未建立 |
1 | 連接已經建立,可以進行通信,或者正在進行通信 |
2 | 連接正在進行關閉,但未完全關閉 |
3 | 連接已經關閉,或者打開連接失敗 |
可以通過 WebSocket創建出來的對象, 即 webSocket.readyState 即可取出狀態。
二.四 WebSocket的四種事件
二.四.一 四種事件
WebSocket共提供了四種事件,來接收處理服務器對客戶端的響應處理。
- open 事件,連接建立時觸發
- close 事件, 連接關閉時觸發,包括手動退出和瀏覽器關閉
- message 事件 客戶端接收服務器數據時觸發
- error 事件, 通信遇到錯誤時,觸發
這四種事件,分別對應了四種事件的處理程序。 (仍然使用的是二.二 創建的 webSocket 對象)。
open 事件 對應 webSocket.onopen
close 事件 對應 webSocket.onclose
message 事件對應 webSocket.onmessage
error 事件對應 webSocket.onerror
二.四.二 事件處理代碼
以 open 事件進行舉例。
二.四.二.一 普通方式
//創建 WebSocket 對象
var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat");
webSocket.onopen = function () {
webSocket.send('Hello WebSocket!');
console.log("連接建立");
}
二.四.二.二 addEventListener() 方式
//創建 WebSocket 對象
var webSocket=new WebSocket("ws://127.0.0.1:80/WebSocket/websocket/chat");
webSocket.addEventListener('open', function (event) {
webSocket.send('Hello WebSocket!');
console.log("連接建立");
});
通常採用第一種方式即可。
二.五 WebSocket的方法 send()和close()
WebSocket 提供了兩種方法,
一種是 send(text) 方法, 用於向服務器端發送數據,
如:
webSocket.send("你好啊服務器,我是兩個蝴蝶飛");
另外一種是 close() 方法, 用於手動關閉瀏覽器連接
如:
webSocket.close();
三. WebSocket 流程分析
(參考了 黑馬培訓教程的 即時通信技術-Websocket實現在線聊天室 資料)
三.一 瀏覽器端發送請求
HEA: GET WebSocket/websocket/chat HTTP/l.l
Host: localhost
Upgrade: webaocket
Conection: Upqrade
oriqin: http://127.0.0.1:80
Pragma: no-cache
Cache-Control: no-cache
Seo-WebSocket-Key:. tSYYnx6EFK/hevZE8JbLaQ--
Sec-KebSocket -Version: 13
vindow. bits. -webkit-deflate-frame
Hoøt: 127.0.0.1:10000
Sec-WebSocket -Extenaiona: permeaaqe-deflater elient. aж
Uaer-Agenti Mozilla/5.0 (Windown NT 6.1; WOW64) AppleMebKit/537.36 (KHTNL, 1ike Gecko)
Chrome/35.0.1916.138 safari/537.36
解釋字段如下:
(1)、Upgrade:表示的意思是“客戶端準備使用websocket協議進行通信,服務端如果支持的話,咱們就換websocket協議吧!”。
(2)、sec-websocket-version: 是指瀏覽器支持的websocket版本號。需注意的是這裏不會出現912的版本號,
因爲websocket協議規定9- 12是保留字段。
(3)、sec-websocket -key:是一一種驗證服務 端是不是支持websocket的驗證算法。
與Response中的sec-websocket -accept是對應的。
(4)、sec-websocket-accept 與sec-websocket-key的對應算法是:
sec . websocket -accept = base64 (hsal (sec websocket -key+ 258EAFA5-E914-47DA-95CA C5AB0DC85B11))
如果返回的sec-websocket-accept不對,在chrome下 會出現Sec-WebSocket -Accept dismatch的錯誤。
(5)、HTTP Staus: Response返回的是101, 代表服務端說“我們雙方後面就按照websocket協議來進行數據傳輸吧!”
三.二 服務器解析
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string
三.三 傳輸數據,雙向傳輸
客戶端發送數據: 服務器, 兩個蝴蝶飛您好
待編碼數據:兩個蝴蝶飛您好
回覆客戶端數據: 兩個蝴蝶飛您好
三.四 客戶端主動斷開連接和服務器端主動斷開連接
當客戶端主動斷開連接時,客戶端會發送http請求,請求斷開連接,服務器端接收請求之後,斷開連接。
當服務器主動斷開連接時,直接斷開連接,所有客戶端得到通知。
謝謝您的觀看!!!