摘要:雖然是點對點通信,但還是需要服務(wù)器來初始化連接,并傳遞一些信息。服務(wù)器實現(xiàn)點對點通信的關(guān)鍵在于兩個瀏覽器之間能直接發(fā)送和接收數(shù)據(jù)包,但一般情況下,瀏覽器或手機都是通過路由器訪問,所以存在網(wǎng)絡(luò)地址轉(zhuǎn)換。
WebRTC
瀏覽器本身不支持相互之間直接建立信道進行通信,都是通過服務(wù)器進行中轉(zhuǎn)。比如現(xiàn)在有兩個客戶端,甲和乙,他們倆想要通信,首先需要甲和服務(wù)器、乙和服務(wù)器之間建立信道。甲給乙發(fā)送消息時,甲先將消息發(fā)送到服務(wù)器上,服務(wù)器對甲的消息進行中轉(zhuǎn),發(fā)送到乙處,反過來也是一樣。這樣甲與乙之間的一次消息要通過兩段信道,通信的效率同時受制于這兩段信道的帶寬。同時這樣的信道并不適合數(shù)據(jù)流的傳輸,如何建立瀏覽器之間的點對點傳輸,一直困擾著開發(fā)者。
WebRTC 是一個開源項目,旨在使得瀏覽器能為實時通信(RTC)提供簡單的 JavaScript 接口。WebRTC 不僅可傳輸視頻,也可以傳輸其他數(shù)據(jù)例如文本、圖片等。需要注意的是,WebRTC 并不是瀏覽器的一個子集,瀏覽器只是根據(jù) WebRTC 的標(biāo)準(zhǔn)協(xié)議實現(xiàn)了 WebRTC 的原生接口。Android 和 IOS 系統(tǒng)也支持 WebRTC 。
WebRTC 應(yīng)用包括下面四個主要的概念:
信令服務(wù)器(Signalling servers)
ICE 服務(wù)器(ICE servers)
媒體服務(wù)器 (Media servers)
JavaScript 接口 (JavaScript API)
信令服務(wù)器信令服務(wù)器主要用于在兩個用戶之間交換信息。雖然 WebRTC 是點對點通信,但還是需要服務(wù)器來初始化連接,并傳遞一些信息。
WebRTC 沒有定義用于建立信道的信令的協(xié)議,因此可以使用任意的傳輸方式,例如 WebSocket, XMPP, SIP, AJAX。
你可以使用實時的傳輸協(xié)議比如 WebSocket 來交換數(shù)據(jù),也可以使用簡單的 GET/POST 方式輪詢服務(wù)器來獲取數(shù)據(jù)。
信令服務(wù)器傳送的數(shù)據(jù)有:
協(xié)商媒體功能和設(shè)置
標(biāo)識和驗證會話參與者的身份
控制媒體會話、指示進度、更改會話和終止會話
其中只有第一項的必備功能。其他都可以根據(jù)業(yè)務(wù)需求自由調(diào)整。
媒體協(xié)商最重要的功能在于,為參與點對點通信的兩個瀏覽器之間交換會話描述協(xié)議(SDP)。SDP 包含瀏覽器的 RTP 媒體棧配置所需的全部信息,包括媒體類型(音頻、視頻、數(shù)據(jù))、所需的編解碼器,用于編解碼器的哥哥參數(shù)或設(shè)置,以及有關(guān)帶寬的信息。此外,信令通道還用于交換候選地址,以便進行 ICE 打洞。
ICE 服務(wù)器實現(xiàn)點對點通信的關(guān)鍵在于兩個瀏覽器之間能直接發(fā)送和接收數(shù)據(jù)包,但一般情況下,瀏覽器或手機都是通過路由器訪問 Internet,所以存在網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)。位于 NAT 之內(nèi)的 IP 地址是私有地址,外部無法訪問。分配給 NAT 的 IP 地址才是公共地址。NAT 每次從內(nèi)部到外部轉(zhuǎn)發(fā)數(shù)據(jù)包時都使用公共地址。
交互式建立連接(ICE)是一種標(biāo)準(zhǔn)穿透協(xié)議,它利用 STUN 和 TURN 服務(wù)器來建立連接。
STUN 服務(wù)器可以遍歷 NAT,獲取瀏覽器的候選地址,包括私有地址、外層 NAT 的公共 IP 地址等。通信信令通道可以交換候選地址,瀏覽器一旦發(fā)送并收到了候選項,就會開始進行連接檢查,若檢查成功,便使用該候選項發(fā)送媒體。
在大多情況下,通過穿透可以建立直接對等連接。但是,若 NAT 或防火墻限制非常嚴(yán)格,無法建立連接,就只能通過 TURN 服務(wù)器中繼媒體。
媒體服務(wù)器媒體服務(wù)器不是必須的,但在多方會話或需要對媒體做額外處理的情況下可以考慮加入。對于有多個瀏覽器參與的會議,可以采用一個集中式媒體服務(wù)器。在這種情況下,美國瀏覽器都只需與媒體服務(wù)器建立單個連接即可,這種結(jié)構(gòu)的優(yōu)勢是額能夠擴展非常大的會話,同時可以在最大限度上減少當(dāng)有新加入者加入會話事美國瀏覽器所需的處理工作量。同時,媒體服務(wù)器也可對媒體進行分析、處理、保存等工作。
JavaScript 接口 getUserMedia通過調(diào)用 navigator.getUserMedia() 可以獲取視頻或音頻的數(shù)據(jù),constraints 參數(shù)可以選擇是否獲取視頻音頻。下面是一個簡單的示例
var constraints = { audio: false, video: true }; var video = document.querySelector("video"); function successCallback(stream) { if (window.URL) { video.src = window.URL.createObjectURL(stream); } else { video.src = stream; } } function errorCallback(error) { console.log("navigator.getUserMedia error: ", error); } navigator.getUserMedia(constraints, successCallback, errorCallback);RTCPeerConnection
RTCPeerConnection 是 WebRTC 中最重要的一個接口,用于確定 ICE 服務(wù)器、交換 SDP。連接過程如下:
創(chuàng)建 RTCPeerConnection 對象
RTCPeerConnection 的參數(shù)用于確定 ICE 服務(wù)器,下面是使用了 google 開放的 STUN 服務(wù)器
let iceServer = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] }; let pc = new RTCPeerConnection(servers);
將媒體流放入 RTCPeerConnection 對象中
pc.addStream(localStream);
通過 offer 和 answer 交換 SDP 描述符
甲和乙各自建立一個PC實例
甲通過 PC 所提供的 createOffer() 方法建立一個包含甲的 SDP 描述符的 offer 信令
甲通過 PC 所提供的 setLocalDescription() 方法,將甲的SDP描述符交給甲的 PC 實例
甲將 offer 信令通過服務(wù)器發(fā)送給乙
乙將甲的 offer 信令中所包含的的SDP描述符提取出來,通過PC所提供的 setRemoteDescription() 方法交給乙的PC實例
乙通過PC所提供的 createAnswer() 方法建立一個包含乙的 SDP 描述符 answer 信令
乙通過PC所提供的 setLocalDescription() 方法,將乙的 SDP 描述符交給乙的PC實例
乙將answer信令通過服務(wù)器發(fā)送給甲
甲接收到乙的answer信令后,將其中乙的SDP描述符提取出來,調(diào)用setRemoteDescripttion()方法交給甲自己的PC實例
ICE 打洞
當(dāng)網(wǎng)絡(luò)候選可用時,通過信令服務(wù)器將其發(fā)送到對方瀏覽器
pc.onicecandidate = function(event) { if (event.candidate) { sendToServer(event.candidate) } };
當(dāng)接受到對方網(wǎng)絡(luò)候選時,將其加入
let candidate = new RTCIceCandidate(candidate); pc.addIceCandidate(candidate);
監(jiān)聽對方發(fā)送的媒體是否可用,并播放媒體
pc.onaddstream = event => { remoteVideo.src = window.URL.createObjectURL(event.stream); }RTCDataChannel
RTCDataChannel 是 RTCPeerConnection API 的一部分,只有在創(chuàng)建了 RTCPeerConnection 實例后才能創(chuàng)建數(shù)據(jù)通道。數(shù)據(jù)通道可以用于發(fā)送文本或是文件。
pc = new RTCPeerConnection(); dc = pc.createDataChannel("dc"); dc.onmessage = event => console.log(event.data); dc.send("text"); dc.sed(new arraybuffer(32))
在另一端可以使用 ondatachannel 獲得 RTCDataChannel 對象
pc.ondatachannel = event => dc = event.channel;參考資料
https://codelabs.developers.g...
https://webrtc.org/
https://segmentfault.com/a/11...
http://www.muazkhan.com/2013/...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/83486.html
摘要:前言本項目旨在從零到壹,制作一款界面精美的聊天軟件。因為本人是開發(fā),設(shè)計功底欠缺,所以軟件設(shè)計的有點丑,如果有大神有更好的,歡迎。 Hola 前言 本項目旨在從零到壹,制作一款界面精美的聊天軟件。 Github 地址因為已工作,所以可能沒有多少時間來繼續(xù)跟進這個項目了,項目可優(yōu)化的點已在下文列出,歡迎大家 Fork 或 Star。 ps: 征 logo 一枚。因為本人是開發(fā),設(shè)計功底...
摘要:下面我們就看一下具體如何申請權(quán)限靜態(tài)權(quán)限申請在項目中的中增加以下代碼動態(tài)權(quán)限申請隨著的發(fā)展,對安全性要求越來越高。其定義如下通過上面的代碼我們就將顯示視頻的定義好了。當(dāng)發(fā)送消息,并收到服務(wù)端的后,其狀態(tài)變?yōu)椤?作者:李超,如遇到相關(guān)問題,可以點擊這里與作者直接交流。 前言 在學(xué)習(xí) WebRTC 的過程中,學(xué)習(xí)的一個基本步驟是先通過 JS 學(xué)習(xí) WebRTC的整體流程,在熟悉了整體流程之后,...
摘要:本質(zhì)上允許網(wǎng)頁程序創(chuàng)建點對點通信,我們將會在隨后的章節(jié)中進行介紹。信令涉及網(wǎng)絡(luò)檢索和穿透,會話創(chuàng)建及管理,通信安全,媒體功能元數(shù)據(jù)和調(diào)制及錯誤處理。這樣就會完全建立及激活節(jié)點間的網(wǎng)絡(luò)套接字會話。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 這是 JavaScript 工作原理第十八章。 概述 何為 WebRTC ?首先,字面上已經(jīng)...
閱讀 2282·2021-10-09 09:41
閱讀 1745·2019-08-30 15:53
閱讀 988·2019-08-30 15:52
閱讀 3443·2019-08-30 11:26
閱讀 767·2019-08-29 16:09
閱讀 3421·2019-08-29 13:25
閱讀 2259·2019-08-26 16:45
閱讀 1931·2019-08-26 11:51