WebRTC 是長期戰爭中的新前線,保護開放且不受干擾的網路。
JavaScript 發明家 Brendan Eich
無需外掛程式即可進行即時通訊
想像一下,手機、電視和電腦都能透過通用平台進行通訊。想像一下,您可以在網頁應用程式中新增視訊通訊和點對點資料分享功能,這是 WebRTC 的願景。
想試試嗎?WebRTC 適用於電腦版和行動版 Google Chrome、Safari、Firefox 和 Opera。我們建議您從 appr.tc 的簡易視訊通訊應用程式著手:
- 在瀏覽器中開啟 appr.tc。
- 按一下「加入」加入聊天室,讓應用程式使用網路攝影機。
- 在新分頁中開啟網頁末端顯示的網址,最好還是在其他電腦上開啟。
快速入門
沒有時間閱讀這篇文章或只想寫程式嗎?
- 如要概略瞭解 WebRTC,請觀看以下 Google I/O 大會影片,或觀看這些投影片:
- 如果尚未使用
getUserMedia
API,請參閱「在 HTML5 中擷取音訊和視訊」和 simpl.info getUserMedia。 - 如要瞭解
RTCPeerConnection
API,請參閱以下範例和「'simpl.info RTCPeerConnection'」。 - 如要瞭解 WebRTC 如何使用伺服器進行訊號,以及防火牆與 NAT 週遊功能,請參閱 appr.tc 中的程式碼和控制台記錄。
- 等不及想立即試用 WebRTC 嗎?請嘗試超過 20 個示範模式,藉此執行 WebRTC JavaScript API。
- 您的裝置和 WebRTC 有問題?造訪 WebRTC 疑難排解工具。
您也可以直接跳至 WebRTC 程式碼研究室。這份逐步指南會說明如何建構完整的視訊通訊應用程式,包括簡易訊號伺服器。
WebRTC 歷史記錄非常短
網路環境最後一個挑戰之一,就是能透過語音和視訊進行人類通訊:即時通訊或 RTC (簡稱 RTC)。在網頁應用程式中,RTC 應該就像在文字輸入中輸入文字一樣自然。如果沒有 AI,創新和開發新互動方式的能力將受到限制。
RTC 一直以來都是企業和複雜的公司,他們需要昂貴的音訊和視訊技術才能取得授權或自行開發。將 RTC 技術與現有內容、資料和服務整合既困難又耗時,尤其是在網路上。
Gmail 視訊通訊在 2008 年大受歡迎;2011 年,Google 推出了採用 Talk (跟 Gmail 一樣) 的 Hangouts 功能。Google 購買 GIPS,這家公司開發了 RTC 所需的許多元件,例如轉碼器和回音消除技術。Google 將由 GIPS 開發的技術開放原始碼,並與網際網路工程任務組 (IETF) 和全球資訊網協會 (World Wide Web Consortium,W3C) 的相關標準機構參與,以確保業界達成共識。Ericsson 在 2011 年 5 月建構了 WebRTC。
WebRTC 採用開放標準,進行即時無外掛程式的即時視訊、音訊和資料通訊。真正的需求:
- 許多網路服務都使用 RTC,但還需要下載、原生應用程式或外掛程式。包括 Skype、Facebook 和 Hangouts。
- 外掛程式的下載作業複雜、容易出錯且令人不悅。
- 外掛程式難以部署、偵錯、疑難排解、測試與維護,而且可能需要授權及整合複雜昂貴的技術。一開始很難說服使用者安裝外掛程式!
WebRTC 專案的指導原則在於 API 的 API 應為開放原始碼、免費、標準化、內建於網路瀏覽器,且效率超越現有技術。
我們現在在哪裡?
WebRTC 常用於許多應用程式,例如 Google Meet。WebRTC 也已經與 WebKitGTK+ 和 Qt 原生應用程式整合。
WebRTC 實作以下三個 API:
- MediaStream
(也稱為 getUserMedia
)
- RTCPeerConnection
- RTCDataChannel
定義 API 時,有兩種規格:
Chrome、Safari、Firefox、Edge 和 Opera 皆支援行動裝置和電腦上的這三個 API。
getUserMedia
:如需示範和程式碼,請參閱 WebRTC 範例,或試試 Chris Wilson 的幾個重要範例,這些範例將 getUserMedia
做為網路音訊的輸入內容。
RTCPeerConnection
:如需簡易示範和功能完整的視訊通訊應用程式,請參閱 WebRTC 範例對等互連連線和 appr.tc。這個應用程式會使用 adapter.js;這個 JavaScript 填充是由 Google 在 WebRTC 社群的協助下維護的 JavaScript 填充,能夠抽離瀏覽器的差異和規格變更。
RTCDataChannel
:如要查看實際運作情形,請參閱「WebRTC 範例」,查看其中一個 Data-channel 示範。
WebRTC 程式碼研究室將說明如何使用全部三個 API 建構簡單的應用程式,以便進行視訊通訊和檔案共用。
您的第一個 WebRTC
WebRTC 應用程式需要執行以下作業:
- 取得串流音訊、影片或其他資料。
- 取得網路資訊 (例如 IP 位址和通訊埠) 並與其他 WebRTC 用戶端 (稱為「對等互連」) 交換,藉此啟用連線,甚至透過 NAT 和防火牆。
- 協調訊號通訊以回報錯誤及啟動或關閉工作階段。
- 交換媒體和用戶端功能相關資訊,例如解析度和轉碼器。
- 傳達串流音訊、影片或資料。
為了取得及通訊串流資料,WebRTC 會實作下列 API:
MediaStream
可存取資料串流,例如透過使用者的攝影機和麥克風。RTCPeerConnection
支援音訊或視訊通話,並提供加密和頻寬管理設備。RTCDataChannel
支援點對點對一般資料進行通訊。
(我們稍後會針對網路與信號各方面進行詳細討論)。
MediaStream
API (又稱為 getUserMedia
API)
MediaStream
API 代表已同步的媒體串流。舉例來說,從攝影機和麥克風輸入擷取的串流會同步處理視訊與音軌。(請勿將 MediaStreamTrack
與 <track>
元素混為一談,後者是完全不同的元素)。
理解 MediaStream
API 最簡單的方法是從外部檢視:
- 透過瀏覽器前往 WebRTC 範例
getUserMedia
。 - 開啟控制台。
- 檢查全域範圍內的
stream
變數。
每個 MediaStream
都有一個輸入內容 (可能是 getUserMedia()
產生的 MediaStream
),以及輸出內容 (可傳遞至影片元素或 RTCPeerConnection
)。
getUserMedia()
方法會採用 MediaStreamConstraints
物件參數,並傳回可解析為 MediaStream
物件的 Promise
。
每個 MediaStream
都有 label
,例如 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
。getAudioTracks()
和 getVideoTracks()
方法會傳回 MediaStreamTrack
陣列。
以 getUserMedia
範例來說,stream.getAudioTracks()
會傳回空陣列 (因為沒有音訊),且假設已連接有效的網路攝影機,stream.getVideoTracks()
會傳回一個 MediaStreamTrack
陣列,代表從網路攝影機拍攝的串流。每個 MediaStreamTrack
都有種類 ('video'
或 'audio'
)、label
(類似 'FaceTime HD Camera (Built-in)'
),代表音訊或影片的一或多個聲道。在這種情況下,只有一個視訊軌不會聽到聲音,但很容易想像的應用情況有很多,例如可透過前置鏡頭串流播放的即時通訊應用程式、後置鏡頭、麥克風,以及分享畫面的應用程式。
設定 srcObject
屬性即可將 MediaStream
附加至影片元素。這項設定先前會將 src
屬性設為使用 URL.createObjectURL()
建立的物件網址,但是已淘汰。
getUserMedia
也可用來做為 Web Audio API 的輸入節點:
// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
console.log('Sorry! Web Audio not supported.');
}
// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;
// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;
navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
// Create an AudioNode from the stream.
const mediaStreamSource =
audioContext.createMediaStreamSource(stream);
mediaStreamSource.connect(filterNode);
filterNode.connect(gainNode);
// Connect the gain node to the destination. For example, play the sound.
gainNode.connect(audioContext.destination);
});
以 Chromium 為基礎的應用程式和擴充功能也可以整合 getUserMedia
。在資訊清單新增 audioCapture
和/或 videoCapture
權限後,系統只會在安裝時要求及授予一次權限。在那之後,系統不會要求使用者授予相機或麥克風存取權。
「getUserMedia()
」只需授予一次權限。不久後,瀏覽器的資訊列會顯示「允許」按鈕。getUserMedia()
的 HTTP 存取權已歸類為強大的功能,因此 Chrome 已於 2015 年底淘汰這項 HTTP 存取權。
該目的可能會為任何串流資料來源啟用 MediaStream
,而不只是相機或麥克風。如此一來,就能從儲存的資料或任意資料來源 (例如感應器或其他輸入來源) 進行串流。
getUserMedia()
必須與其他 JavaScript API 和程式庫搭配使用,才真正發揮效用。
- Webcam Toy 為自動攝影應用程式,可利用 WebGL 添加奇怪的特效,造成可分享或儲存在本機的相片。
- FaceKat 是一款使用 headtrackr.js 打造的臉部追蹤遊戲。
- ASCII 相機會使用 Canvas API 產生 ASCII 圖片。
限制
您可以使用限制條件來設定 getUserMedia()
的影片解析度值。這也適用於其他限制條件,例如顯示比例、面向模式 (前置或後置鏡頭)、影格速率、高度和寬度,以及 applyConstraints()
方法。
如需範例,請參閱「WebRTC 範例 getUserMedia
:選取解析度」。
如果設定不允許的限制值,系統就會提供 DOMException
或 OverconstrainedError
(舉例來說,如果無法要求的解析度)。如要查看實際運作情形,請參閱 WebRTC 範例 getUserMedia
:選取解析度示範模式。
螢幕畫面和分頁擷取
Chrome 應用程式也能透過 chrome.tabCapture
和 chrome.desktopCapture
API,分享單一瀏覽器分頁或整個桌面的即時影像。(如需示範和詳細資訊,請參閱「使用 WebRTC 分享螢幕畫面」一文)。雖然這篇文章只有幾年發布,但內容仍然有趣)。
您也可以透過實驗性的 chromeMediaSource
限制,在 Chrome 中使用螢幕畫面擷取做為 MediaStream
來源。請注意,螢幕畫面擷取需要使用 HTTPS。建議您僅在透過指令列標記啟用擷取功能 (如這篇文章所述) 的情況下使用,因此才應用於開發。
信號:工作階段控制設定、網路和媒體資訊
WebRTC 會使用 RTCPeerConnection
在瀏覽器之間傳遞串流資料 (也稱為對等項目),但還需要一個機制來協調通訊及傳送控制訊息,這個流程也稱為「信號」。WebRTC「不」指定訊號方法和通訊協定。信號並不屬於 RTCPeerConnection
API。
WebRTC 應用程式開發人員可以改用他們偏好的任何訊息通訊協定 (例如 SIP 或 XMPP),以及任何適當的雙雙 (雙向) 通訊管道。appr.tc 範例使用 XHR 和 Channel API 做為信號機制。程式碼研究室會使用在 Node 伺服器上執行的 Socket.io。
信號可用於交換三種資訊:
- 工作階段控制訊息:初始化或關閉通訊及回報錯誤。
- 網路設定:至外部,您的電腦 IP 位址和通訊埠為何?
- 媒體功能:瀏覽器和要與哪個瀏覽器進行通訊時可以處理哪些轉碼器和解析度?
必須先順利完成透過訊號交換資訊交換作業,才能開始點對點串流模式。
例如,假設小艾想和小包溝通。以下是 W3C WebRTC 規格的程式碼範例,這是顯示信號程序的實際運作情形。程式碼會假設存在在 createSignalingChannel()
方法中建立的部分信號機制。另請注意,在 Chrome 和 Opera 中,RTCPeerConnection
目前加上前置字串。
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// Send the offer to the other peer.
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
首先,小莉和 Bob 會交換網路資訊。(尋找候選項目運算式是指使用 ICE 架構尋找網路介面和通訊埠的程序)。
- Alice 會建立含有
onicecandidate
處理常式的RTCPeerConnection
物件,該處理常式會在網路候選項目可供使用時執行。 - Alice 會透過所使用的任何訊號管道 (例如 WebSocket 或其他機制),將序列化的候選資料傳送給 Bob。
- 當志明收到 Alice 的候選訊息時,他會呼叫
addIceCandidate
,將候選項目加入遠端對等點說明。
WebRTC 用戶端 (在本範例中稱為對等點,或稱 Alice 和 Bob) 也需要確定並交換本機和遠端的音訊及視訊媒體資訊,例如解析度和轉碼器功能。只要使用工作階段說明通訊協定 (SDP) 交換「產品」和「答案」,即可交換媒體設定資訊的行為:
- 小艾會執行
RTCPeerConnection
createOffer()
方法。傳回的結果會傳遞RTCSessionDescription
- Alice 的本機工作階段說明。 - 在回呼中,Alice 會使用
setLocalDescription()
設定本機說明,然後透過信號管道將此工作階段說明傳送給 Bob。請注意,在呼叫setLocalDescription()
後,RTCPeerConnection
才會開始收集候選內容。以上資訊請參閱 JSEP IETF 草稿。 - 白先生使用
setRemoteDescription()
將說明設為遠端說明。 - Bob 執行
RTCPeerConnection
createAnswer()
方法,並傳遞他從 Alice 取得的遠端說明,以便產生能與她相容的本機工作階段。createAnswer()
回呼會傳遞RTCSessionDescription
。Bob 將這個值設為本地商家簡介,並傳送給 Alice。 - 當 Alice 取得小明的工作階段說明時,會使用
setRemoteDescription
將其設為遠端說明。 - 重要通知!
RTCSessionDescription
物件是符合工作階段說明通訊協定的 blob,也就是 SDP。已序列化的 SDP 物件如下所示:
v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126
// ...
a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810
網路與媒體資訊的收購與交易平台可以同時完成,但都必須先完成這兩個程序,才能在同業之間串流播放音訊和視訊。
前述的優惠/答案架構稱為「JavaScript 工作階段建立通訊協定」(簡稱 JSEP)。以下的 Ericsson 示範影片中說明瞭首次實作 WebRTC 時的信號和串流程序,有一段非常感謝的動畫。
信號程序順利完成後,即可在呼叫端和受呼叫端之間,直接透過點對點傳送資料。如果傳送失敗,則會透過中介轉發伺服器進行串流 (詳情請參閱稍後說明)。串流是指 RTCPeerConnection
的工作。
RTCPeerConnection
RTCPeerConnection
是 WebRTC 元件,能處理對等點之間的串流資料穩定且有效率的通訊。
以下是顯示 RTCPeerConnection
角色的 WebRTC 架構圖表。如你所知,綠色零件很複雜!
從 JavaScript 的角度來看,這張圖的重點是讓 RTCPeerConnection
能夠保護網頁開發人員免於遭受潛伏的眾多複雜問題。WebRTC 使用的轉碼器和通訊協定會執行大量工作,以實現即時通訊,即使網路不穩定也不例外:
- 封包遺失隱藏功能
- 取消回音
- 頻寬調整
- 動態時基誤差緩衝
- 自動增益控制
- 雜訊抑制和抑制
- 圖片清理
先前的 W3C 程式碼顯示從信號的角度來看,簡化 WebRTC 範例。以下提供兩個運作中 WebRTC 應用程式的逐步操作說明。第一個是示範 RTCPeerConnection
的簡單範例,第二個則是完全運作的視訊通訊用戶端。
RTCPeerConnection 不使用伺服器
以下程式碼是取自 WebRTC 範例對等互連連線,此連線具備本機「和」遠端 RTCPeerConnection
(以及本機和遠端影片) 的網頁。這並不算是非常有用的東西 (呼叫端和受呼叫者位於相同頁面),但會更清楚地顯示 RTCPeerConnection
API 的運作方式,因為網頁上的 RTCPeerConnection
物件可以直接交換資料和訊息,不必使用中介信號機制。
在這個範例中,pc1
代表本機對等點 (呼叫端),pc2
則代表遠端對等點 (受呼叫者)。
來電者
- 建立新的
RTCPeerConnection
並新增getUserMedia()
中的串流: ```js // 伺服器是選用設定檔,(稍後請參閱 TURN 和 STUN 討論內容)。 pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream);) });
- 建立優惠,並將其設為
pc1
的本地說明,且設為pc2
的遠端說明。呼叫端和受呼叫者都位於同一個頁面,因此不必使用信號就能直接在程式碼中完成這項操作:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
受呼叫者
- 建立
pc2
,然後在新增pc1
的串流時,在影片元素中顯示該串流:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
RTCPeerConnection
API 加上伺服器
不過在現實世界中,WebRTC 需要伺服器,所以可能實現以下目標:
- 使用者會發現彼此,並交換真實資訊,例如姓名。
- WebRTC 用戶端應用程式 (對等點) 交換網路資訊。
- 同類應用程式交換的媒體資料,例如影片格式和解析度。
- WebRTC 用戶端應用程式週遊於 NAT 閘道和防火牆。
也就是說,WebRTC 需要四種類型的伺服器端功能:
- 探索及通訊
- 訊號
- NAT/防火牆週遊
- 轉發伺服器 (以免點對點通訊失敗)
網路位址轉譯 (NAT) 遍歷、點對點網路,以及針對使用者探索和信號建構伺服器應用程式的需求,不在本文的討論範圍內。簡單來說,ICE 架構會使用 STUN 通訊協定及其擴充功能 TURN,讓 RTCPeerConnection
能因應 NAT 週遊和其他網路差異。
ICE 是一種架構,可用於與同事 (例如兩個視訊通訊用戶端) 建立連結。ICE 一開始會嘗試「直接」透過 UDP 與對等節點連線,藉此縮短延遲時間。在這個程序中,STUN 伺服器有一項工作:讓 NAT 背後的對等互連得以找出其公開位址和通訊埠。(如要進一步瞭解 STUN 和 TURN,請參閱「建構 WebRTC 應用程式所需的後端服務」)。
如果 UDP 失敗,ICE 會嘗試 TCP。如果直接連線失敗 (尤其是因為企業 NAT 遍歷和防火牆),ICE 會使用中介 (轉送) TURN 伺服器。也就是說,ICE 會先使用 STUN 搭配 UDP,直接連線對等點,如果連線失敗,則會改用 TURN 轉發伺服器。尋找候選項目運算式是指尋找網路介面和通訊埠的程序。
WebRTC 工程師 Justin Uberti 在 2013 年 Google I/O WebRTC 簡報中,提供了更多有關 ICE、STUN 和 TURN 的資訊。(簡報投影片提供了 TURN 和 STUN 伺服器的實作範例。)
簡易的視訊通訊用戶端
如要試用 WebRTC,建議使用 STUN 伺服器完成 WebRTC,開始運用訊號進行網路位址轉譯 (NAT)/防火牆週遊,是 appr.tc 的視訊通訊示範影片。此應用程式使用 adapter.js,這個填充碼可用來將應用程式與規格變更和前置字串差異隔離。
在記錄中刻意輸入重複的程式碼。請查看控制台瞭解事件順序。以下是這個程式碼的詳細逐步操作說明。
網路拓撲
WebRTC 目前僅支援一對一通訊,但可用於較複雜的網路情境,例如讓多個對等點直接相互通訊,或是透過多點控制單元 (MCU) 伺服器 (可處理大量參與者進行選擇性串流轉送,以及混音或錄製音訊和視訊)。
許多現有的 WebRTC 應用程式都只能呈現網路瀏覽器之間的通訊,但閘道伺服器可讓在瀏覽器上執行的 WebRTC 應用程式與裝置互動,例如電話 (也稱為 PSTN) 和 VOIP 系統。2012 年 5 月,Doubango Telecom 以 WebRTC 和 WebSocket 建構的 sipml5 SIP 用戶端,可用於在 iOS 和 Android 上執行的瀏覽器和應用程式之間,啟用視訊通話功能。在 Google I/O 大會上,Tethr 和 Tropo 使用 OpenBTS 手機在公事包中示範災難復原架構,以便透過 WebRTC 進行功能型手機和電腦之間的通訊。沒有電信業者也能進行電話通訊!
RTCDataChannel
API
除了音訊和視訊外,WebRTC 也支援其他類型的資料的即時通訊。
RTCDataChannel
API 支援點對點交換任意資料,不僅延遲時間短,處理量也高。如需單頁示範,並瞭解如何建構簡單的檔案傳輸應用程式,請分別參閱 WebRTC 範例和 WebRTC 程式碼研究室。
API 有許多可能的用途,包括:
- 遊戲
- 遠端桌面應用程式
- 即時文字即時通訊
- 檔案傳輸
- 分散式網路
這個 API 有多種功能可充分運用 RTCPeerConnection
,並提供功能強大且靈活的點對點通訊功能:
- 正在使用
RTCPeerConnection
工作階段設定 - 設定優先順序的多個同時管道
- 可靠和不可靠的傳送語意
- 內建安全防護 (DTLS) 與壅塞控制
- 能否搭配音訊或視訊使用
語法與 WebSocket 十分類似、包含 send()
方法和 message
事件:
const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
localConnection.createDataChannel('sendDataChannel');
// ...
remoteConnection.ondatachannel = (event) => {
receiveChannel = event.channel;
receiveChannel.onmessage = onReceiveMessage;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
};
function onReceiveMessage(event) {
document.querySelector("textarea#send").value = event.data;
}
document.querySelector("button#send").onclick = () => {
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
};
通訊是直接在瀏覽器之間進行,因此 RTCDataChannel
的運作速度會比 WebSocket 快上許多,即使在與防火牆及 NAT 發生衝突的情況下,必須使用轉發 (TURN) 伺服器。
RTCDataChannel
適用於 Chrome、Safari、Firefox、Opera 和 Samsung Internet。Cube Slam 遊戲會使用這個 API 傳達遊戲狀態。與好友或對熊玩耍!創新的 Sharefest 透過 RTCDataChannel
和 peerCDN 啟用檔案共用功能,讓 WebRTC 對點對點內容發布功能一目瞭然。
如要進一步瞭解 RTCDataChannel
,請參閱 IETF 的草稿通訊協定規格。
安全性
即時通訊應用程式或外掛程式可能透過多種方式侵害安全性。例如:
- 未加密的媒體或資料可能會在瀏覽器之間,或是瀏覽器和伺服器之間遭到攔截。
- 應用程式可能會在使用者不知情的情況下錄製及發布影片或音訊。
- 惡意軟體或病毒可能會在無害的外掛程式或應用程式旁安裝。
WebRTC 提供多項功能來避免這些問題:
- WebRTC 實作會使用安全通訊協定,例如 DTLS 和 SRTP。
- 所有 WebRTC 元件 (包括訊號機制) 都必須加密。
- WebRTC 並非外掛程式。它的元件是在瀏覽器沙箱中執行,而不是在獨立的處理程序中執行。元件不需要另外安裝,而且會在瀏覽器更新時更新。
- 你必須明確授予相機和麥克風存取權,且相機或麥克風正在執行時,使用者介面即可清楚顯示這項資訊。
有關串流媒體安全性的完整討論不在本文的討論範圍。詳情請參閱 IETF 建議的「提議的 WebRTC 安全性架構」。
總結
WebRTC 的 API 和標準可普及化及分散工具,用於電話通訊、遊戲、影片製作、音樂製作和新聞收集等各種內容創作與通訊工具。
科技不會比這更造成乾擾。
正如網誌網誌作者 Phil Edholm 所把:「可能,WebRTC 和 HTML5 都能促進與原始瀏覽器搜尋資訊的即時通訊。」
開發人員工具
- 如要查看進行中工作階段的 WebRTC 統計資料,請前往:
- about://webrtc-internals Chrome
- Opera 中的 opera://webrtc-internals
- Firefox 中的 about:webrtc
- 跨瀏覽器互通性注意事項
- adapter.js 是 Google 維護 WebRTC 的 JavaScript 填充碼,在 WebRTC 社群的協助下,得以提取供應商前置字元、瀏覽器差異和規格變更。
- 如要進一步瞭解 WebRTC 訊號程序,請查看控制台中的 appr.tc 記錄輸出內容。
- 如果數量太多,建議您使用 WebRTC 架構,或甚至使用完整的 WebRTC 服務。
- 無論是錯誤報告和功能要求,都歡迎與我們分享:
瞭解詳情
- Justin Uberti 在 2012 年 Google I/O 大會上發表的 WebRTC 講座
- 艾倫 B. Johnston 和 Daniel C. Burnett 目前在 webrtcbook.com 提供印刷和電子書格式的第三版 WebRTC 書籍。
- webrtc.org 提供 WebRTC 的所有功能,包括示範、說明文件和討論。
- discuss-webrtc 是一個討論 WebRTC 技術討論的 Google 網路論壇。
- @webrtc
- Google Developers Talk 說明文件提供了 NAT 遍歷、STUN、轉送伺服器和候選收集的相關資訊。
- GitHub 上的 WebRTC
- 您可以在 Stack Overflow 中查看解答和針對 WebRTC 相關的問題。
標準和通訊協定
- WebRTC W3C 編輯器草稿
- W3C 編輯器的草稿:媒體擷取和串流 (又稱為
getUserMedia
) - IETF 工作小組夥伴計畫
- IETF WebRTC 資料管道通訊協定草稿
- IETF JSEP 草稿
- IETF 建議採用的標準
- IETF RTCWEB 工作群組網際網路草稿:網路即時通訊用途與需求
WebRTC 支援摘要
MediaStream
和 getUserMedia
API
- Chrome 電腦 18.0.1008 以上版本;Android 29 以上版本的 Google Chrome
- Opera 18 以上版本;適用於 Android 20 以上版本的 Opera
- Opera 12,Opera Mobile 12 (基於 Presto 引擎)
- Firefox 17 以上版本
- Microsoft Edge 16 以上版本
- Safari 11.2 以上版本 (iOS) 和 11.1 以上版本 (MacOS)
- UC 11.8 以上版本 (適用於 Android)
- Samsung Internet 4 以上版本
RTCPeerConnection
API
- Chrome 電腦 20 以上版本;適用於 Android 29 以上版本的 Chrome (無旗標)
- Opera 18 以上版本 (預設為開啟);Android 20 以上版本的 Opera (預設為開啟)
- Firefox 22 以上版本 (預設為開啟)
- Microsoft Edge 16 以上版本
- Safari 11.2 以上版本 (iOS) 和 11.1 以上版本 (MacOS)
- Samsung Internet 4 以上版本
RTCDataChannel
API
- Chrome 26 以上版本的實驗版本,但在 Chrome 26 以上版本中更加穩定 (並與 Firefox 互通性);Android 29 以上版本的 Chrome
- Opera 18 以上版本中的穩定版 (和 Firefox 互通性);適用於 Android 20 以上版本的 Opera
- Firefox 22 以上版本 (預設為開啟)
如要進一步瞭解 API 跨平台支援 (例如 getUserMedia
和 RTCPeerConnection
),請參閱 caniuse.com 和 Chrome 平台狀態。
webrtc.org 說明文件也可取得 RTCPeerConnection
的原生 API。