1. 程式人生 > >websocke前世今生

websocke前世今生

模擬 easy web開發 浪費 rtt row 實現 htm read

註:以下內容來自網上。本人經過加工整理。

1、問什麽要用websocke?

Browser已經支持http協議,為什麽還要開發一種新的WebSocket協議呢?我們知道http協議是一種單向的網絡協議。在建立連接後,它僅僅同意Browser/UA(UserAgent)向WebServer發出請求資源後。WebServer才幹返回對應的數據。而WebServer不能主動的推送數據給Browser/UA,當初這麽設計http協議也是有原因的。如果WebServer能主動的推送數據給Browser/UA,那Browser/UA就太easy受到攻擊,一些廣告商也會主動的把一些廣告信息在不經意間強行的傳輸給client,這不能不說是一個災難。那麽單向的http協議給如今的站點或Web應用程序開發帶來了哪些問題呢?


在http協議上要實現browser獲取server端實時數據的需求(比如:股票實時交易)。往往使用下面兩種方案:

1)polling

這樣的方式就是通過Browser/UA定時的向Webserver發送http的Get請求,server收到請求後,就把最新的數據發回給client(Browser/UA),Browser/UA得到數據後。就將其顯示出來,然後再定期的反復這一過程。盡管這樣能夠滿足需求。可是也仍然存在一些問題,比如在某段時間內Webserver端沒有更新的數據,可是Browser/UA仍然須要定時的發送Get請求過來詢問。那麽Webserver就把曾經的老數據再傳送過來。Browser/UA把這些沒有變化的數據再顯示出來,這樣顯然既浪費了網絡帶寬,又浪費了CPU的利用率。假設說把Browser發送Get請求的周期調大一些。就能夠緩解這一問題,可是假設在Webserver端的數據更新非常快時,這樣又不能保證Web應用程序獲取數據的實時性。


2)long polling

它是對Polling的一種改進。

Browser/UA發送Get請求到Webserver,這時Webserver能夠做兩件事情,第一,假設server端有新的數據須要傳送,就馬上把數據發回給Browser/UA,Browser/UA收到數據後。馬上再發送Get請求給Web Server。第二,假設server端沒有新的數據須要發送。這裏與Polling方法不同的是,server不是馬上發送回應給Browser/UA。而是把這個請求保持住,等待有新的數據到來時,再來響應這個請求。當然了。假設server的數據長期沒有更新,一段時間後。這個Get請求就會超時,Browser/UA收到超時消息後。再馬上發送一個新的Get請求給server

。然後依次循環這個過程。

這種方式盡管在某種程度上減小了網絡帶寬和CPU利用率等問題。可是仍然存在缺陷,比如如果server端的數據更新速率較快。server在傳送一個數據包給Browser後必須等待Browser的下一個Get請求到來,才幹傳遞第二個更新的數據包給Browser,那麽這種話,Browser顯示實時數據最快的時間為2×RTT(往返時間),另外在網絡擁塞的情況下,這個應該是不能讓用戶接受的。

另外,因為http數據包的頭部數據量往往非常大(通常有400多個字節),可是真正被server須要的數據卻非常少(有時僅僅有10個字節左右),這種數據包在網絡上周期性的傳輸,難免對網絡帶寬是一種浪費。

2、webSocket協議簡單介紹

WebSocket協議是一種雙向通信協議。它建立在TCP之上,同http一樣通過TCP來數據傳輸。可是它和http最大的不同有兩點:

1.WebSocket是一種雙向通信協議,在建立連接後,WebSocketserver和Browser/UA都能主動的向對方發送或接收數據,就像Socket一樣。不同的是WebSocket是一種建立在Web基礎上的一種簡單模擬Socket的協議。

2.WebSocket須要通過握手連接。類似於TCP它也須要client和server端進行握手連接,連接成功後才幹相互通信。


這裏簡單說明一下WebSocket握手的過程:

當Web應用程序調用new WebSocket(url)接口時,Browser就開始了與地址為url的WebServer建立握手連接的過程。

1. Browser與WebSocketserver通過TCP三次握手建立連接,假設這個建立連接失敗,那麽後面的過程就不會運行。Web應用程序將收到錯誤消息通知。

2. 在TCP建立連接成功後,Browser/UA通過http協議傳送WebSocket支持的版本。協議的字版本,原始地址,主機地址等等一些列字段給server端。

<span style="font-family:Comic Sans MS;">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  </span>
3. WebSocketserver收到Browser/UA發送來的握手請求後,假設數據包數據和格式正確,client和server端的協議版本匹配等等,就接受本次握手連接,並給出對應的數據回復。相同回復的數據包也是採用http協議傳輸。

<span style="font-family:Comic Sans MS;">HTTP/1.1 101 Switching Protocols  
Upgrade: websocket  
Connection: Upgrade  
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=  
Sec-WebSocket-Protocol: chat  </span>
4. Browser收到server回復的數據包後。假設數據包內容、格式都沒有問題的話,就表示本次連接成功,觸發onopen消息,此時Web開發人員就能夠在此時通過send接口想server發送數據。否則,握手連接失敗,Web應用程序會收到onerror消息,而且能知道連接失敗的原因。

3、websocke和http關系:

WebSocket與http協議一樣都是基於TCP的,所以他們都是可靠的協議,Web開發人員調用的WebSocket的send函數在browser的實現中終於都是通過TCP的系統接口進行傳輸的。

WebSocket和Http協議一樣都屬於應用層的協議,那麽他們之間有沒有什麽關系呢?答案是肯定的,WebSocket在建立握手連接時。數據是通過http協議傳輸的。正如我們上一節所示“GET/chat HTTP/1.1”,這裏面用到的僅僅是http協議一些簡單的字段。可是在建立連接之後,真正的傳輸數據階段是不須要http協議參與的。

技術分享


4、websocke瀏覽器端的api:

<span style="font-family:Comic Sans MS;">var wsServer = 'ws://localhost:8888/Demo'; //server地址,這裏是ws開頭。假設是安全websocke使用wss
var websocket = new WebSocket(wsServer); //創建WebSocket對象  
websocket.send("hello");//向server發送消息  
alert(websocket.readyState);//查看websocket當前狀態  
websocket.onopen = function (evt) {  
//已經建立連接  
};  
websocket.onclose = function (evt) {  
//已經關閉連接  
};  
websocket.onmessage = function (evt) {  
//收到server消息,使用evt.data提取  
};  
websocket.onerror = function (evt) {  
//產生異常  
};  </span>

5、wbsocke服務端api說明:

由於WebSocket是一種通訊協議,須要在client(瀏覽器已經幫我們實現)和server端都實現該協議才幹完畢WebSocket的通信。所以server端須要借助一些lib包實現。

tomcat7中websocket的消息格式:

技術分享

詳細能夠參照tomcat7下對websocket的支持返利:http://www.aiuxian.com/article/p-228470.html

websocke前世今生