WebRTC 是長期戰爭中的新戰線,目標是打造開放且不受限制的網路。
JavaScript 發明人 Brendan Eich
不需外掛程式即可進行即時通訊
想像一下,如果手機、電視和電腦都能在同一個平台上通訊,想像一下,如果能輕鬆在網頁應用程式中加入視訊通訊和點對點資料分享功能,會是什麼樣子?這就是 WebRTC 的願景。
想要試試看嗎?Google Chrome、Safari、Firefox 和 Opera 的電腦版和行動版都支援 WebRTC。建議您先從 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 屬於企業專用,且相當複雜,需要授權或自行開發昂貴的音訊和視訊技術。將 RTC 技術與現有內容、資料和服務整合並不容易,而且相當耗時,尤其是在網路上。
Gmail 視訊通話在 2008 年開始流行,而 Google 則在 2011 年推出 Hangouts,同樣使用 Talk (Gmail 也是如此)。Google 收購了 GIPS,這間公司開發了許多 RTC 必備元件,例如編解碼器和迴音消除技術。Google 將 GIPS 開發的技術開放原始碼,並與網際網路工程任務組 (IETF) 和全球資訊網協會 (W3C) 的相關標準機構合作,確保業界共識。2011 年 5 月,Ericsson 首次實作 WebRTC。
WebRTC 採用開放標準,可進行即時視訊、音訊和資料通訊,且無需外掛程式。確實有此需求:
- 許多網路服務都使用 RTC,但需要下載內容、原生應用程式或外掛程式。包括 Skype、Facebook 和 Hangouts。
- 下載、安裝及更新外掛程式的過程複雜、容易出錯,而且令人困擾。
- 外掛程式難以部署、偵錯、排解問題、測試及維護,而且可能需要授權,並與複雜且昂貴的技術整合。說服使用者安裝外掛程式往往很困難!
WebRTC 專案的指導原則是: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 (由 Google 維護的 JavaScript 墊片,並獲得 WebRTC 社群協助),將瀏覽器差異和規格變更抽象化。
RTCDataChannel
:如要查看實際運作情形,請參閱 WebRTC 範例,並查看其中一個資料通道示範。
WebRTC 程式碼研究室說明如何使用這三種 API 建構簡單的視訊通訊和檔案共用應用程式。
您的第一個 WebRTC
WebRTC 應用程式需要執行下列幾項操作:
- 取得串流音訊、視訊或其他資料。
- 取得 IP 位址和通訊埠等網路資訊,並與其他 WebRTC 用戶端 (稱為「對等互連」) 交換資訊,即使透過 NAT 和防火牆也能建立連線。
- 協調信號通訊,回報錯誤並啟動或關閉工作階段。
- 交換媒體和用戶端功能資訊,例如解析度和轉碼器。
- 傳輸串流音訊、視訊或資料。
為取得及傳輸串流資料,WebRTC 會實作下列 API:
MediaStream
存取資料串流,例如來自使用者攝影機和麥克風的資料。RTCPeerConnection
可進行語音或視訊通話,並提供加密和頻寬管理功能。RTCDataChannel
可讓一般資料進行對等通訊。
(本文稍後會詳細討論 WebRTC 的網路和信號傳輸層面)。
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)'
),並代表一或多個音訊或影片管道。在本例中,只有一個視訊軌,沒有音訊,但很容易想像有更多軌的使用情況,例如從前置鏡頭、後置鏡頭、麥克風取得串流的即時通訊應用程式,以及分享螢幕的應用程式。
如要將 MediaStream
附加至影片元素,請設定 srcObject
屬性。先前,這是透過將 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()
屬於強大功能,Chrome 已在 2015 年底淘汰 HTTP 存取權。
這項功能可能適用於任何串流資料來源,而不僅限於攝影機或麥克風。MediaStream
這樣就能從儲存的資料或任意資料來源 (例如感應器或其他輸入內容) 串流資料。
getUserMedia()
與其他 JavaScript API 和程式庫搭配使用時,效果更為顯著:
- Webcam Toy 是一款拍照亭應用程式,可使用 WebGL 為相片加上奇特有趣的效果,並分享或儲存到本機。
- FaceKat 是以 headtrackr.js 建構的臉部追蹤遊戲。
- ASCII Camera 使用 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 做為信號機制。本codelab使用在 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);
}
};
首先,Alice 和 Bob 會交換網路資訊。(「尋找候選項目」是指使用 ICE 架構尋找網路介面和通訊埠的程序)。
- Alice 建立
RTCPeerConnection
物件,並使用onicecandidate
處理常式,在網路候選項目可用時執行。 - Alice 會透過 WebSocket 或其他機制等信號傳輸管道,將序列化候選資料傳送給 Bob。
- 當 Bob 收到 Alice 的候選訊息時,他會呼叫
addIceCandidate
,將候選項目新增至遠端對等互連說明。
WebRTC 用戶端 (也稱為對等互連,或本例中的 Alice 和 Bob) 也需要確認並交換本機和遠端音訊與視訊媒體資訊,例如解析度和轉碼器功能。使用「工作階段描述通訊協定」(SDP) 交換提案和回覆,即可進行信號交換,取得媒體設定資訊:
- 小莉執行
RTCPeerConnection
createOffer()
方法。傳回的內容會傳遞RTCSessionDescription
- Alice 的本機工作階段說明。 - 在回呼中,Alice 會使用
setLocalDescription()
設定本機說明,然後透過信號管道將這個工作階段說明傳送給 Bob。請注意,系統必須呼叫setLocalDescription()
,RTCPeerConnection
才會開始收集候選人。這項做法已編入 JSEP IETF 草案。 - Bob 使用
setRemoteDescription()
將 Alice 傳送給他的說明設為遠端說明。 - Bob 執行
RTCPeerConnection
createAnswer()
方法,並將從 Alice 取得的遠端說明傳遞給該方法,以便產生與 Alice 相容的本機工作階段。createAnswer()
回呼會傳遞RTCSessionDescription
。Bob 將該內容設為當地說明,然後傳送給 Alice。 - 當 Alice 收到 Bob 的工作階段說明時,她會使用
setRemoteDescription
將該說明設為遠端說明。 - Ping!
RTCSessionDescription
物件是符合工作階段說明通訊協定 (SDP) 的 Blob。序列化後,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 元件,負責處理對等互連間穩定且有效率的串流資料通訊。
下圖為 WebRTC 架構圖,顯示 RTCPeerConnection
的角色。如您所見,綠色部分相當複雜!

從 JavaScript 的角度來看,這張圖主要說明 RTCPeerConnection
可保護網頁開發人員,避免受到底層的各種複雜情況影響。WebRTC 使用的轉碼器和通訊協定做了大量工作,即使透過不可靠的網路,也能實現即時通訊:
- 封包遺失隱藏
- 消除回音
- 頻寬適應性
- 動態抖動緩衝
- 自動增益控制
- 降噪和抑制
- 圖片清理
先前的 W3C 程式碼從信號傳輸的角度,簡化了 WebRTC 範例。以下是兩個可正常運作的 WebRTC 應用程式逐步導覽。第一個是簡單的範例,用來示範 RTCPeerConnection
,第二個則是可完整運作的視訊通訊用戶端。
沒有伺服器的 RTCPeerConnection
下列程式碼取自 WebRTC 範例的對等互連,其中包含一個網頁上的本機和遠端 RTCPeerConnection
(以及本機和遠端影片)。這並非非常實用的做法 (呼叫端和被呼叫端位於同一網頁),但由於網頁上的 RTCPeerConnection
物件可以直接交換資料和訊息,不必使用中介信號機制,因此有助於進一步瞭解 RTCPeerConnection
API 的運作方式。
在本例中,pc1
代表本機對等互連 (呼叫端),pc2
則代表遠端對等互連 (被呼叫端)。
來電者
- 建立新的
RTCPeerConnection
,並從getUserMedia()
新增串流: ```js // Servers is an optional configuration file. (請參閱後續的 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 );
Callee
- 建立
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 穿越、對等互連網路,以及建立伺服器應用程式以供使用者探索和發出信號的相關規定,不在本文討論範圍內。簡單來說,STUN 通訊協定及其擴充功能 TURN,是由 ICE 架構使用,可讓 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 伺服器完成信號傳輸和 NAT/防火牆穿越,建議前往 appr.tc 體驗視訊通訊示範。這個應用程式使用 adapter.js,這是一種墊片,可避免應用程式受到規格變更和前置字串差異的影響。
程式碼的記錄內容刻意採用詳細格式,請查看控制台,瞭解事件順序。以下是程式碼的詳細逐步操作說明。
網路拓撲
目前實作的 WebRTC 只支援一對一通訊,但可用於更複雜的網路情境,例如多個對等互連裝置彼此直接通訊,或透過多點控制單元 (MCU) 通訊。MCU 是一種伺服器,可處理大量參與者,並選擇性轉送串流,以及混音或錄製音訊和視訊。

許多現有的 WebRTC 應用程式只會示範網頁瀏覽器之間的通訊,但閘道伺服器可讓瀏覽器執行的 WebRTC 應用程式與裝置互動,例如電話 (也稱為 PSTN) 和 VOIP 系統。2012 年 5 月,Doubango Telecom 開放原始碼的 sipml5 SIP 用戶端以 WebRTC 和 WebSocket 建構而成,可讓瀏覽器與 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);
};
通訊直接在瀏覽器之間進行,因此即使在處理防火牆和 NAT 時,需要使用中繼 (TURN) 伺服器進行穿洞,RTCDataChannel
的速度仍可能比 WebSocket 快上許多。
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 統計資料,請前往:
- Chrome 中的 about://webrtc-internals
- Opera 中的 opera://webrtc-internals
- Firefox 中的 about:webrtc
chrome://webrtc-internals 螢幕截圖
- 跨瀏覽器互通性注意事項
- adapter.js 是 Google 維護的 WebRTC JavaScript 墊片,WebRTC 社群也提供協助,可抽象化供應商前置字元、瀏覽器差異和規格變更。
- 如要進一步瞭解 WebRTC 信號程序,請查看控制台的 appr.tc 記錄輸出內容。
- 如果覺得太複雜,您可能會偏好使用 WebRTC 架構,甚至是完整的 WebRTC 服務。
- 我們非常歡迎您回報錯誤及提出功能要求:
瞭解詳情
- 2012 年 Google I/O 大會上 Justin Uberti 的 WebRTC 講座
- 艾倫 B. Johnston 和 Daniel C. Burnett 維護的 WebRTC 書籍現已出版第三版,提供印刷版和電子書格式,網址為 webrtcbook.com。
- webrtc.org 網站提供所有 WebRTC 相關資訊,包括試用版、說明文件和討論內容。
- discuss-webrtc 是 Google 網路論壇,專門討論 WebRTC 技術。
- @webrtc
- 如要進一步瞭解 NAT 穿越、STUN、中繼伺服器和候選項目收集,請參閱 Google 開發人員 Talk 說明文件。
- GitHub 上的 WebRTC
- Stack Overflow 是尋找 WebRTC 相關解答及提問的好去處。
標準和通訊協定
- WebRTC W3C 編輯器草案
- W3C 編輯器草案:媒體擷取和串流 (也稱為
getUserMedia
) - IETF 工作群組章程
- IETF WebRTC 資料管道通訊協定草案
- IETF JSEP 草案
- IETF 提案的 ICE 標準
- IETF RTCWEB 工作組網際網路草案:網頁即時通訊的使用案例和需求
WebRTC 支援摘要
MediaStream
和 getUserMedia
API
- Chrome 電腦版 18.0.1008 以上版本;Android 版 Chrome 29 以上版本
- Opera 18 以上版本;Opera for Android 20 以上版本
- Opera 12、Opera Mobile 12 (以 Presto 引擎為基礎)
- Firefox 17 以上版本
- Microsoft Edge 16 以上版本
- iOS 上的 Safari 11.2 以上版本,以及 macOS 上的 Safari 11.1 以上版本
- Android 裝置搭載 UC 11.8 以上版本
- Samsung Internet 4 以上版本
RTCPeerConnection
API
- Chrome 電腦版 20 以上版本;Chrome Android 版 29 以上版本 (無須設定旗標)
- Opera 18 以上版本 (預設為開啟);Opera for Android 20 以上版本 (預設為開啟)
- Firefox 22 以上版本 (預設開啟)
- Microsoft Edge 16 以上版本
- iOS 上的 Safari 11.2 以上版本,以及 macOS 上的 Safari 11.1 以上版本
- Samsung Internet 4 以上版本
RTCDataChannel
API
- Chrome 25 的實驗版本,但 Chrome 26 以上版本更穩定 (且可與 Firefox 互通);Android 版 Chrome 29 以上版本
- Opera 18 以上版本 (穩定版,且可與 Firefox 互通);Opera for Android 20 以上版本
- Firefox 22 以上版本 (預設開啟)
如要進一步瞭解 API 的跨平台支援情形 (例如 getUserMedia
和 RTCPeerConnection
),請參閱 caniuse.com 和 Chrome 平台狀態。
您也可以在 webrtc.org 的說明文件中找到 RTCPeerConnection
的原生 API。