发布时间:2013 年 11 月 4 日
WebRTC 可实现点对点通信。它需要服务器,以便客户端可以通过称为“信令”的过程交换元数据并协调通信。服务器还可帮助客户端应对网络地址转换器 (NAT) 和防火墙。
在这里,您将学习如何构建信令服务,以及如何处理 STUN 和 TURN 服务器的实际连接问题。您还将了解 WebRTC 应用如何处理多方通话以及如何与 VoIP 和 PSTN(也称为电话)等服务进行交互。
什么是信令?
信令是协调通信的过程。为了让 WebRTC 应用设置通话,其客户端需要交换以下信息:
- 用于打开或关闭通信的会话控制消息
- 错误消息
- 媒体元数据,例如编解码器、编解码器设置、带宽和媒体类型
- 用于建立安全连接的关键数据
- 网络数据,例如外部世界看到的主机 IP 地址和端口
此信令过程需要一种让客户端来回传递消息的方法。 WebRTC API 未实现该机制。而是需要自行构建
为什么 WebRTC 未定义信令?
为避免冗余并最大限度地提高与成熟技术的兼容性,WebRTC 标准未指定信令方法和协议。JavaScript 会话建立协议 (JSEP) 概述了此方法:
JSEP 的架构还可避免浏览器必须保存状态,即作为信令状态机运行。例如,如果每次重新加载页面时信令数据都会丢失,就会出现问题。而是可以将信令状态保存在服务器上。
JSEP 要求在对等方之间交换提议和应答(媒体元数据)。提议和应答以会话描述协议 (SDP) 格式进行通信,如下所示:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
...
想知道所有这些 SDP 术语的实际含义吗?请查看互联网工程任务组 (IETF) 示例。
请注意,WebRTC 经过精心设计,因此可以通过修改 SDP 文本中的值,在将 offer 或 answer 设置为本地或远程描述之前对其进行调整。例如,appr.tc 中的 preferAudioCodec() 函数可用于设置默认编解码器和比特率。使用 JavaScript 操作 SDP 有些麻烦,目前正在讨论 WebRTC 的未来版本是否应改用 JSON,但坚持使用 SDP 也有一些优势。
RTCPeerConnection API 和信令:提议、应答和候选
RTCPeerConnection 是 WebRTC 应用用于在对等方之间创建连接以及传输音频和视频的 API。
为了启动此流程,RTCPeerConnection 有两项任务:
- 确定本地媒体条件,例如分辨率和编解码器功能。 这是用于提议和应答机制的元数据。
- 获取应用主机的潜在网络地址,称为候选地址。
确定此本地数据后,必须通过信令机制与远程对等方交换该数据。
假设 Alice 尝试呼叫 Eve。以下是完整的应答机制,其中包含所有详细信息:
- Alice 创建了一个
RTCPeerConnection对象。 - Alice 使用
RTCPeerConnectioncreateOffer()方法创建提议(SDP 会话描述)。 - Alice 使用其 offer 调用
setLocalDescription()。 - Alice 将该 offer 字符串化,并使用信令机制将其发送给 Eve。
- Eve 使用 Alice 的 offer 调用
setRemoteDescription(),以便她的RTCPeerConnection了解 Alice 的设置。 - Eve 调用
createAnswer(),并且此调用的成功回调会传递本地会话描述,即 Eve 的应答。 - Eve 通过调用
setLocalDescription()将其应答设置为本地描述。 - 然后,Eve 使用信令机制将她的字符串化应答发送给 Alice。
- Alice 使用
setRemoteDescription()将 Eve 的应答设置为远程会话描述。
Alice 和 Eve 还需要交换网络信息。“查找候选对象”一词是指使用 ICE 框架查找网络接口和端口的过程。
- Alice 使用
onicecandidate处理程序创建RTCPeerConnection对象。 - 当候选网络可用时,系统会调用该处理程序。
- 在处理程序中,Alice 通过信令通道将字符串化的候选数据发送给 Eve。
- 当 Eve 收到来自 Alice 的候选消息时,她会调用
addIceCandidate()将候选添加到远程对等端描述中。
JSEP 支持 ICE 候选地址涓流,这允许主叫方在初始提议后逐步向被叫方提供候选地址,并允许被叫方开始处理通话并建立连接,而无需等待所有候选地址到达。
为 WebRTC 编写信令代码
以下代码段是一个 W3C 代码示例,总结了完整的信令流程。该代码假定存在某种信令机制 SignalingChannel。稍后将更详细地讨论信令。
// 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);
}
};
// After 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);
}
};
如需查看实际的提议-应答和候选交换过程,请访问 simpl.info RTCPeerConnection,并查看单页视频聊天示例的控制台日志。您可以从 Google Chrome 中的 about://webrtc-internals 页面或 Opera 中的 opera://webrtc-internals 页面下载 WebRTC 信令和统计信息的完整转储。
对等发现
这是一种委婉的说法,意思是“我该如何找到可以交谈的人?”
对于电话,您有电话号码和目录。对于在线视频聊天和消息传递,您需要身份和在线状态管理系统,以及用户发起会话的方式。WebRTC 应用需要一种方式,让客户端能够相互发出信号,表明他们想要发起或加入通话。
WebRTC 未定义对等方发现机制,因此我们在此处不探讨相关选项。该过程可以很简单,例如通过电子邮件或消息发送网址。对于视频聊天应用(例如 Talky、tawk.to 和 Browser Meeting),您可以通过分享自定义链接来邀请他人加入通话。开发者 Chris Ball 构建了一个有趣的无服务器 WebRTC 实验,让 WebRTC 通话参与者可以通过他们喜欢的任何消息传递服务(例如即时通讯、电子邮件或信鸽)交换元数据。
如何构建信令服务?
重申一下,WebRTC 标准未定义信令协议和机制。无论您选择哪种方式,都需要一个中间服务器来在客户端之间交换信令消息和应用数据。遗憾的是,Web 应用无法在互联网上大喊:“帮我连接到我的朋友!”
幸运的是,信令消息很小,并且大多在通话开始时交换。在通过 appr.tc 进行视频聊天会话的测试中,信令服务总共处理了大约 30-45 条消息,所有消息的总大小约为 10KB。
除了对带宽要求相对较低之外,WebRTC 信令服务也不会消耗太多处理能力或内存,因为它们只需要中继消息并保留少量会话状态数据,例如哪些客户端已连接。
将消息从服务器推送到客户端
用于信令的消息服务需要是双向的:客户端到服务器和服务器到客户端。双向通信与 HTTP 客户端/服务器请求/响应模型不符,但多年来,人们开发了各种黑客技术(例如长轮询),以便将数据从 Web 服务器上运行的服务推送到浏览器中运行的 Web 应用。
EventSource API 支持服务器发送的事件,即通过 HTTP 从 Web 服务器发送到浏览器客户端的数据。EventSource 专为单向消息传递而设计,但可以与 XHR 结合使用,以构建用于交换信令消息的服务。信令服务通过 EventSource 将消息推送给被叫方,从而传递由 XHR 请求递送的主叫方消息。
WebSocket 专为全双工客户端-服务器通信而设计,这意味着消息可以同时在两个方向上流动。使用纯 WebSocket 或服务器发送事件 (EventSource) 构建的信令服务的一个优势是,这些 API 的后端可以在大多数 Web 托管软件包通用的各种 Web 框架上实现,适用于 PHP、Python 和 Ruby 等语言。
所有支持 WebRTC 的浏览器也都支持 WebSocket。 所有连接都应使用 TLS,以确保消息不会在未加密的情况下被拦截,并减少代理遍历问题。如需详细了解 WebSocket 和代理遍历,请参阅 Ilya Grigorik 的高性能浏览器网络中的 WebRTC 章节。
您可以通过让 WebRTC 客户端通过 Ajax 重复轮询消息传递服务器来处理信令,但这会导致大量冗余网络请求,这对于移动设备来说尤其成问题。即使在会话建立后,对等方也需要轮询信令消息,以防其他对等方发生更改或会话终止。WebRTC Book 应用示例采用此选项,并对轮询频率进行了一些优化。
扩缩信号
虽然信令服务为每个客户端消耗的带宽和 CPU 相对较少,但热门应用的信令服务器可能必须处理来自不同位置的大量消息,且并发级别很高。流量很大的 WebRTC 应用需要能够处理大量负载的信令服务器。这里不作详细介绍,但有许多选项可用于大容量、高性能的消息传递,包括:
可扩展消息处理和现场协议 (XMPP) 是为即时通讯而开发的协议,可用于信令。服务器实现包括 ejabberd 和 Openfire。JavaScript 客户端(例如 Strophe.js)使用 BOSH 模拟双向流式传输,但与 WebSocket 相比,BOSH 的效率可能较低,且扩缩能力较差。
开源库,例如 ZeroMQ(TokBox 在其 Rumour 服务中使用)和 OpenMQ(NullMQ 通过 WebSocket 使用 STOMP 协议将 ZeroMQ 概念应用于 Web 平台)。
商业 WebRTC 平台,例如 vLine
在 Node 上使用 Socket.io 构建信令服务
以下是 Web 应用的代码,该应用使用在 Node 上通过 Socket.io 构建的信令服务。Socket.io 的设计使构建用于交换消息的服务变得更加容易,并且由于其内置的聊天室概念,Socket.io 特别适合 WebRTC 信令。此示例专为相对较少的用户而设计,不适用于生产环境。
Socket.io 使用 WebSocket 及其后备:AJAX 长轮询、AJAX 多部分流式传输、Forever Iframe 和 JSONP 轮询。它已被移植到各种后端,但最著名的可能是本示例中使用的 Node 版本。
此示例中没有 WebRTC。它旨在展示如何将信令构建到 Web 应用中。查看控制台日志,了解客户端加入聊天室并交换消息时发生的情况。此 WebRTC Codelab 提供了有关如何将其集成到完整 WebRTC 视频聊天应用中的分步说明。
以下是客户端 index.html:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
以下是客户端中引用的 JavaScript 文件 main.js:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
下面是完整的服务器应用:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
如需在 localhost 上运行此应用,您需要安装 Node.js、Socket.IO 和 node-static。如需安装 Socket.IO 和 node-static,请在应用目录中从终端运行 npm:
npm install socket.io
npm install node-static
如需启动服务器,请在应用目录中打开终端并运行以下命令:
node server.js
在浏览器中,打开 localhost:2013。在任意浏览器中打开新的标签页或窗口,然后再次打开 localhost:2013。如需查看正在发生的情况,请查看控制台。在 Chrome 和 Opera 中,您可以通过 Google Chrome 开发者工具使用 Ctrl+Shift+J(在 Mac 上为 Command+Option+J)访问控制台。
无论您选择哪种信令方法,您的后端和客户端应用都需要提供与此示例类似的服务。
信号陷阱
- 在调用
setLocalDescription()之前,RTCPeerConnection不会开始收集候选对象。JSEP IETF 草案对此有强制规定。 - 利用 Trickle ICE。候选人一到,就立即调用
addIceCandidate()。
现成的信号服务器
如果您不想自行构建,可以使用多个 WebRTC 信令服务器,这些服务器像前面的示例一样使用 Socket.IO,并与 WebRTC 客户端 JavaScript 库集成:
- webRTC.io 是 WebRTC 的首批抽象库之一。
- Signalmaster 是一个信令服务器,专为与 SimpleWebRTC JavaScript 客户端库搭配使用而创建。
如果您根本不想编写任何代码,可以从 vLine、OpenTok 和 Asterisk 等公司获取完整的商业 WebRTC 平台。
顺便提一下,在 WebRTC 发展初期,Ericsson 在 Apache 上使用 PHP 构建了一个信令服务器。现在,这有点过时了,但如果您正在考虑类似的事情,那么值得查看一下代码。
信号安全
所有 WebRTC 组件都必须进行加密。
不过,WebRTC 标准并未定义信令机制,因此您需要自行确保信令安全。如果攻击者成功劫持了信令,他们就可以停止会话、重定向连接以及记录、更改或注入内容。
确保信令安全的最重要因素是使用安全协议:HTTPS 和 WSS,例如 TLS。这样可以确保消息不会在未加密的情况下被拦截。此外,请注意不要以其他呼叫者可以使用同一信令服务器访问的方式广播信令消息。
应对 NAT 和防火墙
对于元数据信号,WebRTC 应用使用中间服务器,但对于会话建立后的实际媒体和数据流式传输,RTCPeerConnection 会尝试直接或点对点连接客户端。
在更简单的世界中,每个 WebRTC 端点都具有一个唯一地址,该地址可以与其他对等端交换,以便直接通信。
实际上,大多数设备都位于一层或多层 NAT 之后,有些设备安装了会屏蔽特定端口和协议的杀毒软件,还有许多设备位于代理和企业防火墙之后。防火墙和 NAT 实际上可能由同一设备(例如家用 Wi-Fi 路由器)实现。
WebRTC 应用可以使用 ICE 框架来克服现实世界中网络环境的复杂性。如需启用此功能,您的应用必须将 ICE 服务器网址传递给 RTCPeerConnection。
ICE 会尝试找到连接对等端的最佳路径。它会并行尝试所有可能性,并选择最有效的选项。ICE 首先会尝试使用从设备操作系统和网卡获取的主机地址建立连接。如果失败(对于 NAT 后面的设备,会失败),ICE 会使用 STUN 服务器获取外部地址,如果失败,流量会通过 TURN 中继服务器路由。
换句话说,STUN 服务器用于获取外部网络地址,而 TURN 服务器用于在直接(点对点)连接失败时中继流量。
每个 TURN 服务器都支持 STUN。TURN 服务器是具有额外内置中继功能的 STUN 服务器。ICE 还能应对 NAT 设置的复杂性。实际上,NAT 打洞可能不仅仅需要公共 IP:端口地址。
STUN 和 TURN 服务器的网址由 WebRTC 应用在 iceServers 配置对象(RTCPeerConnection 构造函数的第一个参数)中指定(可选)。对于 appr.tc,该值如下所示:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
RTCPeerConnection 获得这些信息后,ICE 就会自动发挥作用。RTCPeerConnection 使用 ICE 框架来确定对等方之间的最佳路径,并根据需要与 STUN 和 TURN 服务器配合使用。
STUN
NAT 为设备提供一个 IP 地址,以便在专用本地网络中使用,但此地址不能在外部使用。如果没有公共地址,WebRTC 对等方就无法进行通信。为了解决此问题,WebRTC 使用了 STUN。
STUN 服务器位于公共互联网上,只有一项任务:检查传入请求(来自在 NAT 后面运行的应用)的 IP:端口地址,并将该地址作为响应发送回来。换句话说,应用会使用 STUN 服务器从公共角度发现其 IP:端口。此过程使 WebRTC 对等方能够为自己获取可公开访问的地址,然后通过信令机制将其传递给另一个对等方,以便建立直接链接。
STUN 服务器不需要执行太多操作或记住太多内容,因此相对低规格的 STUN 服务器可以处理大量请求。
大多数 WebRTC 通话都使用 STUN 成功建立连接,但对于位于防火墙和复杂 NAT 配置后面的对等方之间的通话,连接成功率可能会较低。
TURN
RTCPeerConnection 尝试通过 UDP 在对等方之间建立直接通信。如果失败,RTCPeerConnection 会回退到 TCP。如果失败,则可以使用 TURN 服务器作为后备,在端点之间中继数据。
重申一下,TURN 用于在对等方之间中继音频、视频和数据流,而不是信令数据!
TURN 服务器具有公共地址,因此即使对等方位于防火墙或代理后面,也可以与对等方联系。TURN 服务器只有一项任务:中继数据流。与 STUN 服务器不同,它们本身会消耗大量带宽。
此图展示了 TURN 的运作方式。纯 STUN 未成功,因此每个对等方都求助于使用 TURN 服务器。
部署 STUN 和 TURN 服务器
为了进行测试,Google 运行了一个公共 STUN 服务器 stun.l.google.com:19302,供 appr.tc 使用。对于生产 STUN/TURN 服务,请使用 rfc5766-turn-server。GitHub 上提供了 STUN 和 TURN 服务器的源代码,您还可以在其中找到有关服务器安装的多个信息来源的链接。此外,还提供 Amazon Web Services 虚拟机映像。
另一种 TURN 服务器是 restund,它以源代码形式提供,也适用于 AWS。您可以在 Compute 上设置 restund:
- 根据需要为 tcp=443、udp/tcp=3478 开放防火墙。
- 创建四个实例,每个公共 IP 一个,使用标准 Ubuntu 12.06 映像。
- 设置本地防火墙配置(允许来自任何来源的任何流量)。
- 安装工具:
shell sudo apt-get install make sudo apt-get install gcc - 从 creytiv.com/re.html 安装 libre。
- 从 creytiv.com/restund.html 提取 restund 并解压缩。
wgethancke.name/restund-auth.patch,并使用patch -p1 < restund-auth.patch应用。- 为 libre 和 restund 运行
make、sudo make install。 - 根据您的需求调整
restund.conf(替换 IP 地址并确保其包含相同的共享密钥),然后复制到/etc。 - 将
restund/etc/restund复制到/etc/init.d/。 - 配置 restund:
- 设置
LD_LIBRARY_PATH。 - 将
restund.conf复制到/etc/restund.conf。 - 将
restund.conf设置为使用右侧的 10。无需使用外部IP地址
- 设置
- 运行 restund
- 使用远程机器上的 stund 客户端进行测试:
./client IP:port
多方 WebRTC
您可能还需要查看 Justin Uberti 提出的 IETF 标准,了解用于访问 TURN 服务的 REST API。
媒体流式传输有许多应用场景,不限于一对一通话。例如,一组同事之间的视频会议,或有一个演讲者和数百或数百万观众的公开活动。
WebRTC 应用可以使用多个 RTCPeerConnection,以便每个端点都连接到网格配置中的每个其他端点。这是 talky.io 等应用采用的方法,对于少数对等端来说效果非常好。除此之外,处理和带宽消耗会变得过高,尤其是对于移动客户端。
或者,WebRTC 应用可以选择一个端点,以星形配置将数据流分发到所有其他端点。也可以在服务器上运行 WebRTC 端点,并构建您自己的重新分发机制(webrtc.org 提供了一个示例客户端应用)。
一个 RTCPeerConnection 中的 MediaStream 可用作
另一个 的输入。这可以实现更灵活的架构,因为它使 Web 应用能够通过选择要连接到的其他对等方来处理呼叫路由。如需查看实际应用,请参阅 WebRTC 示例:对等连接中继和 WebRTC 示例:多个对等连接。
多点控制单元
对于大量端点,更好的选择是使用多点控制单元 (MCU)。这是一种服务器,可作为桥梁在大量参与者之间分发媒体。MCU 可以处理视频会议中的不同分辨率、编解码器和帧速率;处理转码;进行选择性流转发;以及混合或录制音频和视频。对于多方通话,需要考虑许多问题,尤其是如何显示多个视频输入以及如何混合来自多个来源的音频。云平台(例如 vLine)也会尝试优化流量路由。
您可以购买完整的 MCU 硬件套件,也可以自行组装。
有多种开源 MCU 软件可供选择。例如,Licode(以前称为 Lynckia)为 WebRTC 提供了开源 MCU。OpenTok 拥有 Mantis。
浏览器之外:VoIP、电话和消息传递
WebRTC 的标准化特性使得在浏览器中运行的 WebRTC 应用与在其他通信平台(例如电话或视频会议系统)上运行的设备或平台之间建立通信成为可能。
SIP 是 VoIP 和视频会议系统使用的信令协议。为了实现 WebRTC Web 应用与 SIP 客户端(例如视频会议系统)之间的通信,WebRTC 需要一个代理服务器来中介信令。信令必须流经网关,但一旦建立通信,SRTP 流量(视频和音频)就可以在对等方之间流动。
公共交换电话网 (PSTN) 是所有“传统”模拟电话的电路交换网络。对于 WebRTC Web 应用与电话之间的通话,流量必须通过 PSTN 网关。同样,WebRTC Web 应用需要一个中介 XMPP 服务器来与 Jingle 端点(例如即时通讯客户端)进行通信。Jingle 是 Google 开发的 XMPP 扩展,可为消息服务提供语音和视频功能。当前的 WebRTC 实现基于 C++ libjingle 库,该库是最初为 Talk 开发的 Jingle 实现。
许多应用、库和平台都利用了 WebRTC 与外部世界通信的能力。例如:
了解详情
- 阅读 WebRTC API 文档。
- WebRTC Codelab 提供了有关如何使用在 Node 上运行的 Socket.io 信令服务构建视频和文本聊天应用的分步说明。
- Chris Wilson 的 SFHTML5 演示:WebRTC 应用简介
这本 350 页的书籍 WebRTC: APIs and RTCWEB Protocols of the HTML5 实时 Web 提供了有关数据和信令路径的大量详细信息,并包含许多详细的网络拓扑图。