Google 在 2010 年發(fā)布了 SPDY(取自 SPeeDY延刘,發(fā)音同 speedy),其開發(fā)目標(biāo)旨在解決 HTTP 的性能瓶頸芒澜,縮短 Web 頁面的加載時(shí)間(50%)
HTTP的瓶頸
1)一條連接上只可發(fā)送一條請求
2)請求只能客戶端開始义辕。客戶端不可以接收除響應(yīng)以外的指令
3)請求/響應(yīng)未經(jīng)壓縮就發(fā)送淮阐、首部信息越多延遲越大
4)發(fā)送冗長的首部叮阅。發(fā)次都發(fā)送相同的首部浪費(fèi)較多
5)可任意選擇壓縮的數(shù)據(jù)格式刁品。非強(qiáng)制壓縮發(fā)送
SPDY的設(shè)計(jì)和功能
SPDY沒有完全改寫HTTP協(xié)議,而是在TCP/IP的應(yīng)用層和傳輸層之間通過新加會(huì)話層的形式運(yùn)作
SPDY以會(huì)話層的形式加入浩姥,控制對數(shù)據(jù)的流動(dòng)挑随,但還是采用HTTP建立連接
使用SPDY,HTTP協(xié)議額外獲得以下功能:
多路復(fù)用:通過單一的TCP連接勒叠,可以無限制處理多個(gè)HTTP請求
賦予請求優(yōu)先級:可以給請求逐個(gè)分配優(yōu)先級兜挨,解決因低寬帶而導(dǎo)致響應(yīng)變慢的問題
壓縮HTTP首部:壓縮HTTP請求的首部和響應(yīng)的首部,減少數(shù)據(jù)包數(shù)量和發(fā)送的字節(jié)數(shù)
推送功能:支持服務(wù)器主動(dòng)向客戶端推送數(shù)據(jù)功能眯分,不用等待客戶端的請求
服務(wù)器提示功能:服務(wù)端可以主動(dòng)提示客戶端請求所需的資源
WebSocket的設(shè)計(jì)和功能
WebSocket拌汇,即Web瀏覽器和Web服務(wù)器之間全雙工通信標(biāo)準(zhǔn)
一旦Web服務(wù)器和客戶端建立起WebScoket協(xié)議通信連接,之后所有的通信都依靠這個(gè)協(xié)議進(jìn)行
由于是建立在HTTP基礎(chǔ)上的協(xié)議弊决,因此連接的發(fā)起方仍是客戶端噪舀,一旦建立連接,任意一方都可直接發(fā)送報(bào)文
WebSocket協(xié)議的主要特點(diǎn):
推送功能:支持由服務(wù)端直接向客戶端推送數(shù)據(jù)飘诗,而不用等待客戶端的請求
減少通信量:它的首部信量很少与倡,因此通信量也相應(yīng)減少
為了實(shí)現(xiàn)WebSocket通信,在HTTP連接建立后昆稿,需要完成一次“握手”的步驟:
握手*請求:為了實(shí)現(xiàn)WebSocket通信纺座,需要在HTTP的首部添加Upgrade字段,告知服務(wù)器協(xié)議發(fā)送改變
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Sec-WebSocket-Key是握手必不可少的鍵值
Sec-WebSocket-Protocol是使用的子協(xié)議
握手*響應(yīng):返回狀態(tài)碼101Switching Protocols的響應(yīng)
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Accept是握手請求中Sec-WebSocket-Key的字段值生成的
成功握手后溉潭,通信時(shí)不再使用HTTP的數(shù)據(jù)幀净响,采用WebSocket獨(dú)立的數(shù)據(jù)幀
WebSocket的API
JavaScript 可調(diào)用“The WebSocket API”(http://www.w3.org/TR/websockets/,由 W3C 標(biāo)準(zhǔn)制定)內(nèi)提供的 WebSocket 程序接口喳瓣,以實(shí)現(xiàn) WebSocket 協(xié)議下全雙工通信别惦。
50ms發(fā)送一次數(shù)據(jù)實(shí)例:
var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function () {
setInterval(function() {
if (socket.bufferedAmount == 0)
socket.send(getUpdateData());
}, 50);
};
想要進(jìn)一步了解WebSocket,看這里