WebSocket --為什么引入WebSocket協議


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

讓我們來看一個案例,現在假設我們想開發一個基於Web的應用程序去獲取當前Web服務器的實時數據,例如股票的實時行情,火車票的剩余票數等等,這就需要Browser/UA與WebServer端之間反復的進行http通信,Browser不斷的發送Get請求,去獲取當前的實時數據。下面介紹幾種常見的方式:

1.     Polling

這種方式就是通過Browser/UA定時的向Web服務器發送http的Get請求,服務器收到請求后,就把最新的數據發回給客戶端(Browser/UA),Browser/UA得到數據后,就將其顯示出來,然后再定期的重復這一過程。雖然這樣可以滿足需求,但是也仍然存在一些問題,例如在某段時間內Web服務器端沒有更新的數據,但是Browser/UA仍然需要定時的發送Get請求過來詢問,那么Web服務器就把以前的老數據再傳送過來,Browser/UA把這些沒有變化的數據再顯示出來,這樣顯然既浪費了網絡帶寬,又浪費了CPU的利用率。如果說把Browser發送Get請求的周期調大一些,就可以緩解這一問題,但是如果在Web服務器端的數據更新很快時,這樣又不能保證Web應用程序獲取數據的實時性。

2.     Long Polling

上面介紹了Polling遇到的問題,現在介紹一下LongPolling,它是對Polling的一種改進。

Browser/UA發送Get請求到Web服務器,這時Web服務器可以做兩件事情,第一,如果服務器端有新的數據需要傳送,就立即把數據發回給Browser/UA,Browser/UA收到數據后,立即再發送Get請求給Web Server;第二,如果服務器端沒有新的數據需要發送,這里與Polling方法不同的是,服務器不是立即發送回應給Browser/UA,而是把這個請求保持住,等待有新的數據到來時,再來響應這個請求;當然了,如果服務器的數據長期沒有更新,一段時間后,這個Get請求就會超時,Browser/UA收到超時消息后,再立即發送一個新的Get請求給服務器。然后依次循環這個過程。

這種方式雖然在某種程度上減小了網絡帶寬和CPU利用率等問題,但是仍然存在缺陷,例如假設服務器端的數據更新速率較快,服務器在傳送一個數據包給Browser后必須等待Browser的下一個Get請求到來,才能傳遞第二個更新的數據包給Browser,那么這樣的話,Browser顯示實時數據最快的時間為2×RTT(往返時間),另外在網絡擁塞的情況下,這個應該是不能讓用戶接受的。另外,由於http數據包的頭部數據量往往很大(通常有400多個字節),但是真正被服務器需要的數據卻很少(有時只有10個字節左右),這樣的數據包在網絡上周期性的傳輸,難免對網絡帶寬是一種浪費。

通過上面的分析可知,要是在Browser能有一種新的網絡協議,能支持客戶端和服務器端的雙向通信,而且協議的頭部又不那么龐大就好了。WebSocket就是肩負這樣一個使命登上舞台的。

 

  WebSocket協議是一種雙向通信協議,它建立在TCP之上,同http一樣通過TCP來傳輸數據,但是它和http最大的不同有兩點:1.WebSocket是一種雙向通信協議,在建立連接后,WebSocket服務器和Browser/UA都能主動的向對方發送或接收數據,就像Socket一樣,不同的是WebSocket是一種建立在Web基礎上的一種簡單模擬Socket的協議;2.WebSocket需要通過握手連接,類似於TCP它也需要客戶端和服務器端進行握手連接,連接成功后才能相互通信。

下面是一個簡單的建立握手的時序圖:

 

這里簡單說明一下WebSocket握手的過程。

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

1.     Browser與WebSocket服務器通過TCP三次握手建立連接,如果這個建立連接失敗,那么后面的過程就不會執行,Web應用程序將收到錯誤消息通知。

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

例如:

 

[html]  view plain  copy
 
  1. GET /chat HTTP/1.1  
  2. Host: server.example.com  
  3. Upgrade: websocket  
  4. Connection: Upgrade  
  5. Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==  
  6. Origin: http://example.com  
  7. Sec-WebSocket-Protocol: chat,superchat  
  8. Sec-WebSocket-Version: 13  

 

 

3.     WebSocket服務器收到Browser/UA發送來的握手請求后,如果數據包數據和格式正確,客戶端和服務器端的協議版本號匹配等等,就接受本次握手連接,並給出相應的數據回復,同樣回復的數據包也是采用http協議傳輸。

 

[html]  view plain  copy
 
  1. HTTP/1.1 101 Switching Protocols  
  2. Upgrade: websocket  
  3. Connection: Upgrade  
  4. Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=  
  5. Sec-WebSocket-Protocol: chat  


4.     Browser收到服務器回復的數據包后,如果數據包內容、格式都沒有問題的話,就表示本次連接成功,觸發onopen消息,此時Web開發者就可以在此時通過send接口想服務器發送數據。否則,握手連接失敗,Web應用程序會收到onerror消息,並且能知道連接失敗的原因。

 

  WebSocket與http協議一樣都是基於TCP的,所以他們都是可靠的協議,Web開發者調用的WebSocket的send函數在browser的實現中最終都是通過TCP的系統接口進行傳輸的。WebSocket和Http協議一樣都屬於應用層的協議,那么他們之間有沒有什么關系呢?答案是肯定的,WebSocket在建立握手連接時,數據是通過http協議傳輸的,正如我們上一節所看到的“GET/chat HTTP/1.1”,這里面用到的只是http協議一些簡單的字段。但是在建立連接之后,真正的數據傳輸階段是不需要http協議參與的。

具體關系可以參考下圖:

 

TCP、UDP、HTTP、SOCKET、WebSocket之間的區別

TCP/IP協議棧主要分為四層:應用層、傳輸層、網絡層、數據鏈路層, 
每層都有相應的協議,如下圖

IP:

網絡層協議;(高速公路)

TCP和UDP:

傳輸層協議;(卡車)

HTTP:

應用層協議;(貨物)。HTTP(超文本傳輸協議)是利用TCP在兩台電腦(通常是Web服務器和客戶端)之間傳輸信息的協議。客戶端使用Web瀏覽器發起HTTP請求給Web服務器,Web服務器發送被請求的信息給客戶端。

SOCKET:

套接字,TCP/IP網絡的API。(港口碼頭/車站)Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。socket是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調用已實現進程在網絡中通信。

TCP/IP:

代表傳輸控制協議/網際協議,指的是一系列協議,TCP/IP 模型在 OSI 模型的基礎上進行了簡化,變成了四層,從下到上分別為:網絡接口層、網絡層、傳輸層、應用層。與 OSI 體系結構對比如下: 

TCP/UDP區別:

TCP

(傳輸控制協議,Transmission Control Protocol):(類似打電話) 
面向連接、傳輸可靠(保證數據正確性)、有序(保證數據順序)、傳輸大量數據(流模式)、速度慢、對系統資源的要求多,程序結構較復雜, 
每一條TCP連接只能是點到點的, 
TCP首部開銷20字節。

UDP

(用戶數據報協議,User Data Protocol):(類似發短信) 
面向非連接 、傳輸不可靠(可能丟包)、無序、傳輸少量數據(數據報模式)、速度快,對系統資源的要求少,程序結構較簡單 , 
UDP支持一對一,一對多,多對一和多對多的交互通信, 
UDP的首部開銷小,只有8個字節。

tcp三次握手建立連接:

第一次握手:客戶端發送syn包(seq=x)到服務器,並進入SYN_SEND狀態,等待服務器確認; 
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態; 
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。 
握手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。

主機A向主機B發出連接請求數據包:“我想給你發數據,可以嗎?”,這是第一次對話; 
主機B向主機A發送同意連接和要求同步(同步就是兩台主機一個在發送,一個在接收,協調工作)的數據包:“可以,你什么時候發?”,這是第二次對話; 
主機A再發出一個數據包確認主機B的要求同步:“我現在就發,你接着吧!”,這是第三次對話。 
三次“對話”的目的是使數據包的發送和接收同步,經過三次“對話”之后,主機A才向主機B正式發送數據。

Websocket

Websocket協議解決了服務器與客戶端全雙工通信的問題。

注:什么是單工、半雙工、全工通信? 
信息只能單向傳送為單工; 
信息能雙向傳送但不能同時雙向傳送稱為半雙工; 
信息能夠同時雙向傳送則稱為全雙工。

websocket協議解析 
wensocket協議包含兩部分:一部分是“握手”,一部分是“數據傳輸”。

WebSocket和Socket區別

可以把WebSocket想象成HTTP(應用層),HTTP和Socket什么關系,WebSocket和Socket就是什么關系。

HTTP 協議有一個缺陷:通信只能由客戶端發起,做不到服務器主動向客戶端推送信息。

WebSocket 協議在2008年誕生,2011年成為國際標准。所有瀏覽器都已經支持了。 
它的最大特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬於服務器推送技術的一種。

參考:

揭開Socket編程的面紗

圖解TCP-IP協議

Android 進階12:進程通信之 Socket (順便回顧 TCP UDP)

WebSocket與TCP/IP

websocket 歷史及使用詳解

WebSocket 教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM