WebSocket

WebSocket

WebSocket協定是基於TCP的一種新的網路協定。它實現了瀏覽器與伺服器全雙工(full-duplex)通信——允許伺服器主動傳送信息給客戶端。WebSocket通信協定於2011年被IETF定為標準RFC 6455,並被RFC7936所補充規範。

基本信息

概述

TheWebSocketProtocolenablestwo-waycommunicationbetweenaclientrunninguntrustedcodeinacontrolledenvironmenttoaremotehostthathasopted-intocommunicationsfromthatcode.Thesecuritymodelusedforthisistheorigin-basedsecuritymodelcommonlyusedbywebbrowsers.Theprotocolconsistsofanopeninghandshakefollowedbybasicmessageframing,layeredoverTCP.Thegoalofthistechnologyistoprovideamechanismforbrowser-basedapplicationsthatneedtwo-waycommunicationwithserversthatdoesnotrelyonopeningmultipleHTTPconnections(e.g.,usingXMLHttpRequestor<iframe>sandlongpolling).

WebSocket協定支持(在受控環境中運行不受信任的代碼的)客戶端與(選擇加入該代碼的通信的)遠程主機之間進行全雙工通信。用於此的安全模型是Web瀏覽器常用的基於原始的安全模式。協定包括一個開放的握手以及隨後的TCP層上的訊息幀。該技術的目標是為基於瀏覽器的、需要和伺服器進行雙向通信的(伺服器不能依賴於打開多個HTTP連線(例如,使用XMLHttpRequest或<iframe>和長輪詢))應用程式提供一種通信機制

背景

簡單的說,WebSocket協定之前,雙工通信是通過不停傳送HTTP請求,從伺服器拉取更新來實現,這導致了效率低下。WebSocket解決了這個問題。下面是標準RFC6455中的產生背景概述。

Historically,creatingwebapplicationsthatneedbidirectionalcommunicationbetweenaclientandaserver(e.g.,instantmessagingandgamingapplications)hasrequiredanabuseofHTTPtopulltheserverforupdateswhilesendingupstreamnotificationsasdistinctHTTPcalls.

Thisresultsinavarietyofproblems:

oTheserverisforcedtouseanumberofdifferentunderlyingTCPconnectionsforeachclient:oneforsendinginformationtotheclientandanewoneforeachincomingmessage.

oThewireprotocolhasahighoverhead,witheachclient-to-servermessagehavinganHTTPheader.oTheclient-sidescriptisforcedtomaintainamappingfromtheoutgoingconnectionstotheincomingconnectiontotrackreplies.

AsimplersolutionwouldbetouseasingleTCPconnectionfortrafficinbothdirections.ThisiswhattheWebSocketProtocolprovides.CombinedwiththeWebSocketAPI,itprovidesanalternativetoHTTPpollingfortwo-waycommunicationfromawebpagetoaremoteserver.

TheWebSocketProtocolisdesignedtosupersedeexistingbidirectionalcommunicationtechnologiesthatuseHTTPasatransportlayer.Suchtechnologieswereimplementedastrade-offsbetweenefficiencyandreliabilitybecauseHTTPwasnotinitiallymeanttobeusedforbidirectionalcommunication(see[RFC6202]forfurtherdiscussion).[1]

長久以來,創建實現客戶端和用戶端之間雙工通訊的webapp都會造成HTTP輪詢的濫用:客戶端向主機不斷發送不同的HTTP呼叫來進行詢問

這會導致一系列的問題:

1.伺服器被迫為每個客戶端使用許多不同的底層TCP連線:一個用於向客戶端傳送信息,其它用於接收每個傳入訊息。

2.有些協定有很高的開銷,每一個客戶端和伺服器之間都有HTTP頭。

3.客戶端腳本被迫維護從傳出連線到傳入連線的映射來追蹤回復。

一個更簡單的解決方案是使用單個TCP連線雙向通信。這就是WebSocket協定所提供的功能。結合WebSocketAPI,WebSocket協定提供了一個用來替代HTTP輪詢實現網頁到遠程主機的雙向通信的方法。

WebSocket協定被設計來取代用HTTP作為傳輸層的雙向通訊技術,這些技術只能犧牲效率和可依賴性其中一方來提高另一方,因為HTTP最初的目的不是為了雙向通訊。(獲得更多關於此的討論可查閱RFC6202)

原理

WebSocket protocol 是HTML5一種新的協定(protocol)。它是實現了瀏覽器與伺服器全雙工通信(full-duplex)。

現很多網站為了實現即時通訊(real-time),所用的技術都是輪詢(polling)。輪詢是在特定的的時間間隔(time interval)(如每1秒),由瀏覽器對伺服器發出HTTP request,然後由伺服器返回最新的數據給客服端的瀏覽器。這種傳統的HTTP request 的模式帶來很明顯的缺點 – 瀏覽器需要不斷的向伺服器發出請求(request),然而HTTP request 的header是非常長的,裡面包含的數據可能只是一個很小的值,這樣會占用很多的頻寬。

而最比較新的技術去做輪詢的效果是Comet – 用了AJAX。但這種技術雖然可達到全雙工通信,但依然需要發出請求(reuqest)。

在 WebSocket API,瀏覽器和伺服器只需要要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。在此WebSocket 協定中,為我們實現即時服務帶來了兩大好處:

1. Header

互相溝通的Header是很小的-大概只有 2 Bytes

2. Server Push

伺服器可以主動傳送數據給客戶端

握手協定

在實現websocket連線過程中,需要通過瀏覽器發出websocket連線請求,然後伺服器發出回應,這個過程通常稱為“握手” (handshaking)。

PS1:握手協定在後期的版本中,會標明版本編號,下面的例子屬於早期的協定之一,對於新版的 chrome 和 Firefox 皆不適用。

PS2:後期的版本大多屬於功能上的擴充,例如使用第7版的握手協定同樣也適用於第8版的握手協定。

例子:

瀏覽器請求

WebSocketWebSocket
GET /demo HTTP/1.1

Host: 你的網址.com

Connection: Upgrade

Sec-WebSocket-Key2: 12998 5 Y3 1 .P00

Upgrade: WebSocket

Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5

Origin: http://你的網址.com

^n:ds[4U

//2010年之後的新版本websocket協定的Sec-WebSocket-Key只有一個,新的瀏覽只支持一個的,google的phpwebsocket用的是之前的協定所以不能直接運行通過,現在有個新版本是基於這個協定的是php-websocket-server-1

伺服器回應

HTTP/1.1 101

WebSocket Protocol Handshake

Upgrade: WebSocket

Connection: Upgrade

Sec-WebSocket-Origin: http://你的網址.com

Sec-WebSocket-Location: ws://你的網址.com/demo

Sec-WebSocket-Protocol: sample

8jKS’y:G*Co,Wxa-

伺服器返回

Upgrade:websocket

Connection:Upgrade

告訴瀏覽器即將升級的是Websocket協定

Sec-WebSocket-Accept是將請求包“Sec-WebSocket-Key”的值,與”258EAFA5-E914-47DA-95CA-C5AB0DC85B11″這個字元串進行拼接,然後對拼接後的字元串進行sha-1運算,再進行base64編碼得到的。用來說明自己是WebSocket助理伺服器。

Sec-WebSocket-Version是WebSocket協定版本號。RFC6455要求使用的版本是13,之前草案的版本均應當被棄用。

更多握手規範詳見RFC6455。

HTML5

在HTML5中內置有一些API,用於回響應用程式發起的請求。基本API語句如下:

創建對象

varws=newWebSocket(url,name);

url為WebSocket伺服器的地址,name為發起握手的協定名稱,為可選擇項。

傳送文本訊息

ws.send(msg);

msg為文本訊息,對於其他類型的可以通過二進制形式傳送

接收訊息

ws.onmessage=(function(){...})();

錯誤處理

ws.onerror=(function(){...})();

關閉連線

ws.close();

語言支持

WebSocket瀏覽器支持WebSocket瀏覽器支持
所有主流瀏覽器都支持RFC6455。但是具體的WebSocket版本有區別。

phpjettynettyrubyKaazingnginxpythonTomcatDjangoerlang netty.net等語言均可以用來實現支持WebSocket的伺服器。

websocketapi在瀏覽器端的廣泛實現似乎只是一個時間問題了,值得注意的是伺服器端沒有標準的api,各個實現都有自己的一套api,並且tcp也沒有類似的提案,所以使用websocket開發伺服器端有一定的風險.可能會被鎖定在某個平台上或者將來被迫升級。

相關詞條

相關搜尋

熱門詞條

聯絡我們