WebRTC中的信令協議
如何為webRTC專案選擇信令協議
總體來說,有五種不同的webRTC信令協議實現方式:
信令協議_______________它是什麼______________選擇理由
SIP over WebSocket 繼承自VoIP的老頑固 它可以和現在的多數後端建立連線
XMPP/Jingle XMPP的狂熱分子 因為它是基於XMPP的
WebSocket 最流行的時常達人 它是最新的,最功能強大的基於web的C-S通訊協議
XHR/Comet 經典用法 因為webSocket不能在所有的地方使用
Data Channle 尋求刺激分子 webRTC的資料通道是可於信令傳輸的未知領域
一. COMET / XHR / SSE
它是web信令的經典方法。
Comet是一種用於web的技術,能使伺服器能實時地將更新的資訊傳送到客戶端,而無須客戶端發出請求,
目前有兩種實現方式: 長輪詢和iframe流。
. 長輪詢
長輪詢是在開啟一條連線以後保持,等待伺服器推送來資料再關閉的方式。
. iframe流
iframe流方式是在頁面中插入一個隱藏的iframe,利用其src屬性在伺服器和客戶端之間建立一條長連結,
伺服器向iframe傳輸資料(通常是HTML,內有負責插入資訊的javascript),來實時更新頁面。
Comet方式通俗的說就是一種長連線機制(long lived http)。
同樣是由Browser端主動發起請求,但是Server端以一種似乎非常慢的響應方式給出回答。
這樣在這個期間內,伺服器端可以使用同一個connection把要更新的資料主動傳送給Browser。
因此請求可能等待較長的時間,期間沒有任何資料返回,但是一旦有了新的資料,它將立即被髮送到客戶機。
Comet又有很多種實現方式,但是總的來說對Server端的負載都會有增加.
雖然對於單位操作來說,每次只需要建議一次connection,但是由於connection是保持較長時間的,
對於 server端的資源的佔用要有所增加。
優點: 實時性好(訊息延時小);效能好(能支援大量使用者)
缺點: 長期佔用連線,喪失了無狀態高併發的特點。
應用: 股票系統、實時通訊。
它的實現如下圖中所示:
Fig1 基於長輪詢的伺服器推模型
這項技術能在絕大多數的瀏覽中實現,因此它的通用性很好,也易於實現和使用。
唯一的問題是,它的長連線會佔用伺服器端的資源,導致其併發性不好。
對於小規模應用來說,它不是問題。
對於要支援百萬級規模來說,就不要考慮用它了。
NOTE:
Google的原生程式碼中的peerconnection專案就是用這種機制實現的信令互動。
UPDATE: As someone smart pointed out – on its own,
this technique still require you to define your own proprietary signaling messages.
HTTP信令協議示例1
HTTP信令協議示例2
HTTP信令協議示例3
二. WebSocket
WebSocket protocol 是HTML5一種新的協議。
它實現了瀏覽器與伺服器全雙工通訊(full-duplex)。
1.1 WebSocket 前世今生
眾所周知,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 在 IBM、微軟、Google 等巨頭的推動和協作下終於塵埃落地,
正式從草案落實為實際標準規範,各個應用伺服器及瀏覽器廠商逐步開始統一,
在 JavaEE7 中也實現了 WebSocket 協議,從而無論是客戶端還是服務端的 WebSocket 都已完備,
讀者可以查閱HTML5 規範,熟悉新的 HTML 協議規範及 WebSocket 支援。
1.2 WebSocket 機制
WebSocket 是 HTML5 一種新的協議。
它實現了瀏覽器與伺服器全雙工通訊,能更好的節省伺服器資源和頻寬並達到實時通訊,
它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸資料,
但是它和 HTTP 最大不同是:
. WebSocket 是一種雙向通訊協議,
在建立連線後,WebSocket 伺服器和 Browser/Client Agent 都能主動的向對方傳送或接收資料,
就像 Socket 一樣;
. WebSocket 需要類似 TCP 的客戶端和伺服器端通過握手連線,連線成功後才能相互通訊
非 WebSocket 模式傳統 HTTP 客戶端與伺服器的互動如下圖所示:
圖 2. 傳統 HTTP 請求響應客戶端伺服器互動圖
使用 WebSocket 模式客戶端與伺服器的互動如下圖:
圖 3.WebSocket 請求響應客戶端伺服器互動圖
上圖對比可以看出,相對於傳統 HTTP 每次請求-應答都需要客戶端與服務端建立連線的模式,
WebSocket 是類似 Socket 的 TCP 長連線的通訊模式,
一旦 WebSocket 連線建立後,後續資料都以幀序列的形式傳輸。
在客戶端斷開 WebSocket 連線或 Server 端斷掉連線前,不需要客戶端和服務端重新發起連線請求。
在海量併發及客戶端與伺服器互動負載流量大的情況下,極大的節省了網路頻寬資源的消耗,有明顯的效能優勢,
且客戶端傳送和接受訊息是在同一個持久連線上發起,實時性優勢明顯。
我們再通過客戶端和服務端互動的報文看一下 WebSocket 通訊與傳統 HTTP 的不同:
在客戶端,new WebSocket 例項化一個新的 WebSocket 客戶端物件,
連線類似 ws://yourdomain:port/path 的服務端 WebSocket URL,
WebSocket 客戶端物件會自動解析並識別為 WebSocket 請求,
從而連線服務端埠,執行雙方握手過程,客戶端傳送資料格式類似:
清單 1.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”錯誤,並關閉連線。
服務端收到報文後返回的資料格式類似:
清單 2.WebSocket 服務端響應報文
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 及程式碼實現。
1.3 WebSockets的弊端
不是所有的瀏覽器都支援,目前支援的瀏覽器有:
WebSocket客戶端支援
瀏覽器 支援情況
Chrome Chrome version 4+支援
Firefox Firefox version 5+支援
IE IE version 10+支援
Safari IOS 5+支援
Android Brower Android 4.5+支援
也不是所有的web伺服器都支援,目前支援的web伺服器有:
WebSocket 服務端支援
廠商 應用伺服器 備註
IBM WebSphere WebSphere 8.0 以上版本支援,7.X 之前版本結合 MQTT 支援類似的 HTTP 長連線
甲骨文 WebLogic WebLogic 12c 支援,11g 及 10g 版本通過 HTTP Publish 支援類似的 HTTP 長連線
微軟 IIS IIS 7.0+支援
Apache Tomcat Tomcat 7.0.5+支援,7.0.2X 及 7.0.3X 通過自定義 API 支援
Apache Jetty Jetty 7.0+支援
因些,你需要考慮你的應用的架構和網路元件是否能用webSocket.
如果你計劃使用webSocket,還有兩個額外的事情要做:
. Run them over a secured TLS connection,
which in general is what you should do for any WebRTC signaling anyway
. Think of using a hybrid solution like socket.io or SockJS,
which can automatically “downgrade” to COMET mechanisms if WebSockets aren’t available
I’d also use WebSockets whenever.
As in whenever I don’t feel that options 3-5 below make sense to me.
實際上,下面的3~5的選項都不好用。
UPDATE: As someone smart pointed out – on its own,
this technique still require you to define your own proprietary signaling messages.
webSocket信令協議示例1
webSocket信令協議示例2
三、 SIP over WebSocket
SIP(Session Initiation Protocol,會話初始協議)是由IETF
(Internet Engineering Task Force,因特網工程任務組)制定的多媒體通訊協議。
它是一個基於文字的應用層控制協議,用於建立、修改和釋放一個或多個參與者的會話。
廣泛應用於CS(Circuit Switched,電路交換)、
NGN(Next Generation Network,下一代網路)以及
IMS(IP Multimedia Subsystem,IP多媒體子系統)的網路中,
可以支援並應用於語音、視訊、資料等多媒體業務,同時也可以應用於Presence(呈現)、
Instant Message(即時訊息)等特色業務。
可以說,有IP網路的地方就有SIP協議的存在。
SIP是類似於HTTP。SIP可以減少應用特別是高階應用的開發時間。
SIP協議本身是一個成熟的經過考驗的網路通話協議。
SIP協議的流程和包含的信令大致如下:
圖4. SIP資料交換圖
但是,SIP over WebSocket和webSocket類似,只是把SIP搭建在了webSocket上。
實際上它還沒有完成,也不好用。
Ugly as hell, but gets the job done –
especially if what you are looking for is connecting to an existing telephony backend.
Who does this? Asterisk. Those that try to fuze WebRTC to IMS or RCS.
People who need to “gateway” their way into SIP.
Unless you already have a SIP investment in place,
and unless a major part of your use case includes calling to PSTN – don’t use this.
Even if your origins are in VoIP and SIP is your mother tongue.
四、 XMPP/Jingle
XMPP是一種基於標準通用標記語言的子集XML的協議,它繼承了在XML環境中靈活的發展性。
因此,基於XMPP的應用具有超強的可擴充套件性。
經過擴充套件以後的XMPP可以通過傳送擴充套件的資訊來處理使用者的需求,
以及在XMPP的頂端建立如內容釋出系統和基於地址的服務等應用程式。
而且,XMPP包含了針對伺服器端的軟體協議,使之能與另一個進行通話,
這使得開發者更容易建立客戶應用程式或給一個配好系統新增功能。
它和SIP類似,只是另一個叫XMPP的協議罷了。
If you take this route, it is probably either
because you have an existing XMPP installation or you need the presence capabilities that XMPP
comes with out of the box (and with server side implementations readily available).
I am not a fan of XMPP to say the least,
but I don’t really have anything bad to say about this approach.
If you know and like XMPP – go for it.
五、 Data Channel
WebRTC has a data channel. Once an initial connection is made between the two “endpoints”,
you can use the data channel to communication and drive your signaling instead of going via a server.
There are few I’ve seen that use this approach, and it does have merit. If has 3 main benefits:
Latency of signaling messages is lower,
as there’s no server in-between that needs to parse and understand them
Since a server isn’t involved, server scalability improves –
it handles less messages from each connected browser
Improved privacy, simply because tapping into the server gives you less information
UPDATE: As with Comet and WebSockets, you still need to define your messages
when using the data channel.
資料通道信令協議示例1
資料通道信令協議示例2
資料通道信令協議示例3
六、Why is it important?
Selection of the signaling protocol will decide the development effort required for certain features
as well as the cost you pay for it –in setup time of sessions, server performance, etc.
It is a decision that shouldn’t be taken lightly.
–
While we’re here – how about subscribing to my monthly email?
It deals with such questions on… a monthly basis.
參考文件:
1. https://bloggeek.me/siganling-protocol-webrtc/
2. http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/