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