Websocket只是一個網絡通訊協議,就像 http、ftp等都是網絡通訊的協議同樣;
相對於HTTP這種非持久的協議來講,Websocket是一個持久化網絡通訊的協議;html
WebSocket和HTTP的關係web
有交集,可是並非所有。
Websocket只是借用了HTTP的一部分協議來完成一次握手。(HTTP的三次握手,此處只完成一次)ajax
Http 協議瀏覽器
第一次握手:主機A發送位碼爲syn=1,隨機產生seq number=1234567的數據包到服務器,主機B由SYN=1知道,A要求創建聯機;服務器
第二次握手:主機B收到請求後要確認聯機信息,向A發送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=7654321的包websocket
第三次握手:主機A收到後檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ack是否爲1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到後確認seq值與ack=1則鏈接創建成功。網絡
完成三次握手,主機A與主機B開始傳送數據。併發
Long poll 和Ajax輪詢以及WebSocket的原理app
1、Ajax輪詢的原理。socket
場景以下:
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有。。(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:你好煩啊,沒有啊。。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:好啦好啦,有啦給你。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:。。。。。沒。。。。沒。。。沒有(Response) ---- loop
代碼:
var polling = function(url, type, data){ var xhr = new XMLHttpRequest(), type = type || "GET", data = data || null; xhr.onreadystatechange = function(){ if(xhr.readyState == 4) { receive(xhr.responseText); xhr.onreadystatechange = null; } }; xhr.open(type, url, true); //IE的ActiveXObject("Microsoft.XMLHTTP")支持GET方法發送數據, //其它瀏覽器不支持,已測試驗證 xhr.send(type == "GET" ? null : data); }; var timer = setInterval(function(){ polling(); }, 1000);
二、long poll的原理。
long poll 其實原理跟 ajax輪詢 差很少,都是採用輪詢的方式,不過採起的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,
客戶端發起鏈接後,若是沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完以後,客戶端再次創建鏈接,周而復始。
場景以下:
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)
服務端:額。。 (等待到有消息的時候)。。來 給你(Response)
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)
客戶端:啦啦啦啦,有新信息麼?
服務端:月線正忙,請稍後再試(503 Server Unavailable)
客戶端:。。。。好吧,啦啦啦,有新信息麼?
服務端:月線正忙,請稍後再試(503 Server Unavailable)
客戶端:
代碼:
var longPoll = function(type, url){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ // 狀態爲 4,數據傳輸完畢,從新鏈接 if(xhr.readyState == 4) { receive(xhr.responseText); xhr.onreadystatechange = null; longPoll(type, url); } }; xhr.open(type, url, true); xhr.send(); }
而後服務端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。
從上面能夠看出其實這兩種方式,都是在不斷地創建HTTP鏈接,而後等待服務端處理,能夠體現HTTP協議的另一個特色,被動性。
何爲被動性呢,其實就是,服務端不能主動聯繫客戶端,只能有客戶端發起。
缺陷:
從上面很容易看出來,無論怎麼樣,上面這兩種都是很是消耗資源的。
ajax輪詢 須要服務器有很快的處理速度和資源。(速度)
long poll 須要有很高的併發,也就是說同時接待客戶的能力。(場地大小)
因此ajax輪詢 和long poll 都有可能發生這種狀況。
三、WebSocket的原理。
這時Websocket出現了。
他解決了HTTP的這幾個難題。
首先,被動性,當服務器完成協議升級後(HTTP->Websocket),服務端就能夠主動推送信息給客戶端啦。
因此上面的情景能夠作以下修改。
客戶端:啦啦啦,我要創建Websocket協議,須要的服務:chat,Websocket協議版本:17(HTTP Request)
服務端:ok,確認,已升級爲Websocket協議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務端:ok,有的時候會告訴你的。
服務端:balabalabalabala
服務端:balabalabalabala
服務端:哈哈哈哈哈啊哈哈哈哈
服務端:笑死我了哈哈哈哈哈哈哈
可是Websocket只須要一次HTTP握手,因此說整個通信過程是創建在一次鏈接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要查看identity info的信息。
同時由客戶主動詢問,轉換爲服務器(推送)有信息的時候就發送(固然客戶端仍是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不須要佔用自己速度就慢的客服(Handler)了
父親節快到了,常回家看看!
樹欲靜而風不止,子欲孝而親不在!