WebSocket原理說明

WebSocket原理說明

衆所周知,Web應用的通訊過程一般是客戶端經過瀏覽器發出一個請求,服務器端接收請求後進行處理並返回結果給客戶端,客戶端瀏覽器將信息呈現。這種機制對於信息變化不是特別頻繁的應用能夠良好支撐,但對於實時要求高、海量併發的應用來講顯得捉襟見肘,尤爲在當前業界移動互聯網蓬勃發展的趨勢下,高併發與用戶實時響應是Web應用常常面臨的問題,好比金融證券的實時信息、Web導航應用中的地理位置獲取、社交網絡的實時消息推送等。web

傳統的請求-響應模式的Web開發在處理此類業務場景時,一般採用實時通信方案。好比常見的輪詢方案,其原理簡單易懂,就是客戶端以必定的時間間隔頻繁請求的方式向服務器發送請求,來保持客戶端和服務器端的數據同步。其問題也很明顯:當客戶端以固定頻率向服務器端發送請求時,服務器端的數據可能並無更新,帶來不少無謂請求,浪費帶寬,效率低下。瀏覽器

基於Flash,AdobeFlash經過本身的Socket實現完成數據交換,再利用Flash暴露出相應的接口給JavaScript調用,從而達到實時傳輸目的。此方式比輪詢要高效,且由於Flash安裝率高,應用場景普遍。然而,移動互聯網終端上Flash的支持並很差:IOS系統中沒法支持Flash,Android雖然支持Flash但實際的使用效果差強人意,且對移動設備的硬件配置要求較高。2012年Adobe官方宣佈再也不支持Android4.1+系統,宣告了Flash在移動終端上的死亡。服務器

傳統的Web模式在處理高併發及實時性需求的時候,會遇到難以逾越的瓶頸,須要一種高效節能的雙向通訊機制來保證數據的實時傳輸。在此背景下,基於HTML5規範的、有Web TCP之稱的 WebSocket應運而生。早期HTML5並無造成業界統一的規範,各個瀏覽器和應用服務器廠商有着各異的相似實現,如IBM的MQTT、Comet開源框架等。直到2014年,HTML5終於塵埃落地,正式落實爲實際標準規範,各個應用服務器及瀏覽器廠商逐步開始統一,在 JavaEE7中也實現了WebSocket協議。至此不管是客戶端仍是服務端的WebSocket都已完備。用戶能夠查閱HTML5規範,熟悉新的HTML協議規範及WebSocket支持。websocket

WebSocket 機制

如下簡要介紹一下WebSocket的原理及運行機制。網絡

WebSocket是HTML5下一種新的協議。它實現了瀏覽器與服務器全雙工通訊,能更好的節省服務器資源和帶寬並達到實時通信的目的。它與HTTP同樣經過已創建的TCP鏈接來傳輸數據,可是它和HTTP最大不一樣是:併發

WebSocket是一種雙向通訊協議。在創建鏈接後,WebSocket服務器端和客戶端都能主動向對方發送或接收數據,就像Socket同樣;
WebSocket須要像TCP同樣,先創建鏈接,鏈接成功後才能相互通訊。
傳統HTTP客戶端與服務器請求響應模式以下圖所示:
負載均衡

WebSocket模式客戶端與服務器請求響應模式以下圖:
框架

上圖對比能夠看出,相對於傳統HTTP每次請求-應答都須要客戶端與服務端創建鏈接的模式,WebSocket是相似Socket的TCP長鏈接通信模式。一旦WebSocket鏈接創建後,後續數據都以幀序列的形式傳輸。在客戶端斷開WebSocket鏈接或Server端中斷鏈接前,不須要客戶端和服務端從新發起鏈接請求。在海量併發及客戶端與服務器交互負載流量大的狀況下,極大的節省了網絡帶寬資源的消耗,有明顯的性能優點,且客戶端發送和接受消息是在同一個持久鏈接上發起,實時性優點明顯。dom

相比HTTP長鏈接,WebSocket有如下特色:socket

是真正的全雙工方式,創建鏈接後客戶端與服務器端是徹底平等的,能夠互相主動請求。而HTTP長鏈接基於HTTP,是傳統的客戶端對服務器發起請求的模式。
HTTP長鏈接中,每次數據交換除了真正的數據部分外,服務器和客戶端還要大量交換HTTP header,信息交換效率很低。Websocket協議經過第一個request創建了TCP鏈接以後,以後交換的數據都不須要發送 HTTP header就能交換數據,這顯然和原有的HTTP協議有區別因此它須要對服務器和客戶端都進行升級才能實現(主流瀏覽器都已支持HTML5)。此外還有 multiplexing、不一樣的URL能夠複用同一個WebSocket鏈接等功能。這些都是HTTP長鏈接不能作到的。
下面再經過客戶端和服務端交互的報文對比WebSocket通信與傳統HTTP的不一樣點:

在客戶端,new WebSocket實例化一個新的WebSocket客戶端對象,請求相似 ws://yourdomain:port/path 的服務端WebSocket URL,客戶端WebSocket對象會自動解析並識別爲WebSocket請求,並鏈接服務端端口,執行雙方握手過程,客戶端發送數據格式相似:

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

能夠看到,客戶端發起的WebSocket鏈接報文相似傳統HTTP報文,Upgrade:websocket參數值代表這是WebSocket類型請求,Sec-WebSocket-Key是WebSocket客戶端發送的一個 base64編碼的密文,要求服務端必須返回一個對應加密的Sec-WebSocket-Accept應答,不然客戶端會拋出Error during WebSocket handshake錯誤,並關閉鏈接。

服務端收到報文後返回的數據格式相似:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

Sec-WebSocket-Accept的值是服務端採用與客戶端一致的密鑰計算出來後返回客戶端的,HTTP/1.1 101 Switching Protocols表示服務端接受WebSocket協議的客戶端鏈接,通過這樣的請求-響應處理後,兩端的WebSocket鏈接握手成功, 後續就能夠進行TCP通信了。用戶能夠查閱WebSocket協議棧瞭解WebSocket客戶端和服務端更詳細的交互數據格式。

在開發方面,WebSocket API 也十分簡單:只須要實例化 WebSocket,建立鏈接,而後服務端和客戶端就能夠相互發送和響應消息。在WebSocket 實現及案例分析部分能夠看到詳細的 WebSocket API 及代碼實現。

騰訊雲公網有日租類型七層負載均衡轉發部分支持Websocket,目前包括英魂之刃、銀漢遊戲等多家企業已接入使用。當出現不兼容問題時,請修改websocket配置,websocket server不校驗下圖中圈出的字段:

一個使用WebSocket應用於視頻的業務思路以下:

使用心跳維護websocket鏈路,探測客戶端端的網紅/主播是否在線
設置負載均衡7層的proxy_read_timeout默認爲60s
設置心跳爲50s,便可長期保持Websocket不斷開
近期Websocket將開放自定義配置,敬請期待。

本文轉載自:https://www.qcloud.com/document/product/214/4150?fromSource=gwzcw.93403.93403.93403

相關文章
相關標籤/搜索