博客原文地址javascript
建議看這篇以前先看一下使用WebRTC搭建前端視頻聊天室——入門篇html
若是須要搭建實例的話能夠參照SkyRTC-demo:github地址前端
其中使用了兩個庫:SkyRTC(github地址)和SkyRTC-client(github地址)html5
這兩個庫和demo都是我寫的,若是有bug或是錯誤歡迎指出,我會盡力更正java
這篇文章講述了WebRTC中所涉及的信令交換以及聊天室中的信令交換,主要內容來自WebRTC in the real world: STUN, TURN and signaling,我在這裏提取出的一些信息,並添加了本身在開發時的一些想法。git
WebRTC提供了瀏覽器到瀏覽器(點對點)之間的通訊,但並不意味着WebRTC不須要服務器。暫且不說基於服務器的一些擴展業務,WebRTC至少有兩件事必需要用到服務器:
1. 瀏覽器之間交換創建通訊的元數據(信令)必須經過服務器
2. 爲了穿越NAT和防火牆github
咱們須要經過一系列的信令來創建瀏覽器之間的通訊。而具體須要經過信令交換哪些內容呢?這裏大概列了一下:
1. 用來控制通訊開啓或者關閉的鏈接控制消息
2. 發生錯誤時用來彼此告知的消息
3. 媒體流元數據,好比像解碼器、解碼器的配置、帶寬、媒體類型等等
4. 用來創建安全鏈接的關鍵數據
5. 外界所看到的的網絡上的數據,好比IP地址、端口等web
在創建鏈接以前,瀏覽器之間顯然沒有辦法傳遞數據。因此咱們須要經過服務器的中轉,在瀏覽器之間傳遞這些數據,而後創建瀏覽器之間的點對點鏈接。可是WebRTC API中並無實現這些。json
不去由WebRTC實現信令交換的緣由很簡單:WebRTC標準的制定者們但願可以最大限度地兼容已有的成熟技術。具體的鏈接創建方式由一種叫JSEP(JavaScript Session Establishment Protocol)的協議來規定,使用JSEP有兩個好處:
1. 在JSEP中,須要交換的關鍵信息是多媒體會話描述(multimedia session description)。因爲開發者在其所開發的應用程序中信令所使用的協議不一樣(SIP或是XMPP或是開發者本身定義的協議),WebRTC創建呼叫的思想創建在媒體流控制層面上,從而與上層信令傳輸相分離,防止相互之間的信令污染。只要上層信令爲其提供了多媒體會話描述符這樣的關鍵信息就能夠創建鏈接,無論開發者用何種方式來傳遞。
2. JSEP的架構同時也避免了在瀏覽器上保存鏈接的狀態,防止其像一個狀態機同樣工做。因爲頁面常常被頻繁的刷新,若是鏈接的狀態保存在瀏覽器中,每次刷新都會丟失。使用JSEP能使得狀態被保存在服務器上瀏覽器
JSEP將客戶端之間傳遞的信令分爲兩種:offer信令和answer信令。他們主要內容的格式都遵循會話描述協議(Session Description Protocal,簡稱SDP)。一個SDP的信令的內容大體上以下:
v=0 o=- 7806956 075423448571 2 IN IP4 127.0.0.1 s=- t=0 0 a=group:BUNDLE audio video data a=msid-semantic: WMS 5UhOcZZB1uXtVbYAU5thB0SpkXbzk9FHo30g m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126 c=IN IP4 0.0.0.0 a=rtcp:1 IN IP4 0.0.0.0 a=ice-ufrag:grnpQ0BSTSnBLroq a=ice-pwd:N5i4DZKMM2L7FEYnhO8V7Kg5 a=ice-options:google-ice a=fingerprint:sha-256 01:A3:18:0E:36:5E:EF:24:18:8C:8B:0C:9E:B0:84:F6:34:E9:42:E3:0F:43:64:ED:EC:46:2C:3C:23:E3:78:7B a=setup:actpass a=mid:audio a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level a=recvonly a=rtcp-mux a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:qzcKu22ar1+lYah6o8ggzGcQ5obCttoOO2IzXwFV a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10 a=rtpmap:103 ISAC/16000 a=rtpmap:104 ISAC/32000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:106 CN/32000 a=rtpmap:105 CN/16000 a=rtpmap:13 CN/8000 a=rtpmap:126 telephone-event/8000 a=maxptime:60 m=video 1 RTP/SAVPF 100 116 117 c=IN IP4 0.0.0.0 a=rtcp:1 IN IP4 0.0.0.0 a=ice-ufrag:grnpQ0BSTSnBLroq a=ice-pwd:N5i4DZKMM2L7FEYnhO8V7Kg5 a=ice-options:google-ice a=fingerprint:sha-256 01:A3:18:0E:36:5E:EF:24:18:8C:8B:0C:9E:B0:84:F6:34:E9:42:E3:0F:43:64:ED:EC:46:2C:3C:23:E3:78:7B a=setup:actpass a=mid:video a=extmap:2 urn:ietf:params:rtp-hdrext:toffset a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time a=sendrecv a=rtcp-mux a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:qzcKu22ar1+lYah6o8ggzGcQ5obCttoOO2IzXwFV a=rtpmap:100 VP8/90000 a=rtcp-fb:100 ccm fir a=rtcp-fb:100 nack a=rtcp-fb:100 goog-remb a=rtpmap:116 red/90000 a=rtpmap:117 ulpfec/90000 a=ssrc:3162115896 cname:/nERF7Ern+udqf++ a=ssrc:3162115896 msid:5UhOcZZB1uXtVbYAU5thB0SpkXbzk9FHo30g 221b204e-c9a0-4b01-b361-e17e9bf8f639 a=ssrc:3162115896 mslabel:5UhOcZZB1uXtVbYAU5thB0SpkXbzk9FHo30g a=ssrc:3162115896 label:221b204e-c9a0-4b01-b361-e17e9bf8f639 m=application 1 DTLS/SCTP 5000 c=IN IP40.0.0.0 a=ice-ufrag:grnpQ0BSTSnBLroq a=ice-pwd:N5i4DZKMM2L7FEYnhO8V7Kg5 a=ice-options:google-ice