WebSocket協(xié)議
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端。
產(chǎn)生背景
在沒有WebSocket協(xié)議之前,在網(wǎng)頁中,實現(xiàn)一個聊天室只能使用ajax 不斷輪詢,請求服務(wù)器是否有數(shù)據(jù)產(chǎn)生,而這樣的實現(xiàn)方法會出現(xiàn)一系列的問題:
- 如果輪詢時間間隔太短,會導(dǎo)致客戶端和服務(wù)端在一個時間段內(nèi)不斷的進行http tcp的握手/揮手動作和http 請求頭,響應(yīng)頭的傳輸,大量消耗服務(wù)器資源,如果用戶量大的情況,會造成服務(wù)器的繁忙以至于宕機
- 客戶端每次只能通過發(fā)送http 請求獲得服務(wù)器是否有數(shù)據(jù)返回,且數(shù)據(jù)的及時性無法保證
正因為在這種情況下,所以WebSocket出現(xiàn)了,它只需要一次http握手,就可以保持一個長連接,使得服務(wù)器可以主動發(fā)送消息給客戶端,大大減少了輪詢機制的消耗
實現(xiàn)原理
在實現(xiàn)websocket連線過程中,需要通過瀏覽器發(fā)出websocket連線請求,然后服務(wù)器發(fā)出回應(yīng),這個過程通常稱為“握手” 。在 WebSocket API,瀏覽器和服務(wù)器只需要做一個握手的動作,然后,瀏覽器和服務(wù)器之間就形成了一條快速通道。兩者之間就直接可以數(shù)據(jù)互相傳送。在此WebSocket 協(xié)議中,為我們實現(xiàn)即時服務(wù)帶來了兩大好處:
- Header: 互相溝通的Header是很小的-大概只有 2 Bytes
- Server Push: 服務(wù)器的推送,服務(wù)器不再被動的接收到瀏覽器的請求之后才返回數(shù)據(jù),而是在有新數(shù)據(jù)時就主動推送給瀏覽器。
握手協(xié)議
首先,瀏覽器發(fā)起一個http協(xié)議的websocket握手請求:
GET /websocket/HTTP/1.1
Host: localhost
Upgrade: websocket #表示希望將http協(xié)議升級到Websocket協(xié)議。
Connection: Upgrade #表示希望將http協(xié)議升級到Websocket協(xié)議。
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg== #瀏覽器隨機生成的base64 encode的值,用來詢問服務(wù)器是否是支持WebSocket。
Origin: http://服務(wù)器地址
Sec-WebSocket-Version: 13
websocket服務(wù)器響應(yīng):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket #告訴瀏覽器已經(jīng)升級到websocket
Connection: Upgrade #告訴瀏覽器已經(jīng)升級到websocket
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8= #將請求包“Sec-WebSocket-Key”的值,與” 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ″這個字符串進行拼接,然后對拼接后的字符串進行sha-1運算,再進行base64編碼得到的。用來說明自己是WebSocket助理服務(wù)器。
這樣就已經(jīng)是握手成功了,瀏覽器和服務(wù)端已經(jīng)建立了一個websocket通道,發(fā)送數(shù)據(jù)不再需要tcp握手,也不需要發(fā)送http請求頭,服務(wù)端也可自動下發(fā)數(shù)據(jù)到瀏覽器
HTML5 Web Socket API
在HTML5中內(nèi)置有一些API,用于響應(yīng)應(yīng)用程序發(fā)起的請求。基本API語句如下:
var ws = new WebSocket(url,name);//創(chuàng)建對象
ws.send(msg);//發(fā)送文本消息
ws.onmessage = (function(evt/*服務(wù)器發(fā)送數(shù)據(jù)的對象*/){})();//接收消息回調(diào)事件
ws.onerror = (function(evt/*錯誤對象*/){})();//錯誤處理
ws.close();//關(guān)閉連接
其他
可自行搜索了解詳細(xì)內(nèi)容