JavaScript中的WebRTC与实时通信
字数 764 2025-11-15 19:39:31
JavaScript中的WebRTC与实时通信
描述
WebRTC(Web Real-Time Communication)是一组API标准,允许浏览器之间建立点对点的实时音视频流和数据传输,无需安装插件或第三方软件。它包含三个核心API:MediaStream(获取音视频流)、RTCPeerConnection(建立点对点连接)和RTCDataChannel(传输任意数据)。
核心概念与步骤
-
媒体捕获(MediaStream)
- 使用
navigator.mediaDevices.getUserMedia()获取摄像头和麦克风的访问权限 - 示例代码:
const constraints = { video: true, audio: true }; const stream = await navigator.mediaDevices.getUserMedia(constraints); // 将流显示在video元素中 document.getElementById('localVideo').srcObject = stream;
- 使用
-
信令交换(Signaling)
- 问题:WebRTC本身不提供发现和协商机制,需通过信令服务器(如WebSocket)交换元数据
- 交换内容:
- 会话描述(SDP):包括媒体格式、网络信息等
- 网络地址(ICE候选):帮助两端建立直接连接
-
建立点对点连接(RTCPeerConnection)
- 步骤:
a. 创建连接对象:
b. 添加本地媒体流:const pc = new RTCPeerConnection(configuration);
c. 交换SDP描述:stream.getTracks().forEach(track => pc.addTrack(track, stream));- 发起端创建offer并设置本地描述:
const offer = await pc.createOffer(); await pc.setLocalDescription(offer); // 通过信令服务器发送offer给对端 - 接收端设置远程描述后创建answer:
await pc.setRemoteDescription(offer); const answer = await pc.createAnswer(); await pc.setLocalDescription(answer); // 发送answer给发起端
pc.onicecandidate = (event) => { if (event.candidate) { // 通过信令服务器发送候选给对端 } }; // 接收端通过addIceCandidate添加候选 - 发起端创建offer并设置本地描述:
- 步骤:
-
数据传输(RTCDataChannel)
- 在已建立的连接上创建双向数据通道:
const dc = pc.createDataChannel('chat'); dc.onmessage = (event) => console.log('收到消息:', event.data); dc.send('Hello!');
- 在已建立的连接上创建双向数据通道:
完整流程示例
// 信令模拟(假设已通过WebSocket实现)
const signaling = {
send: (data) => websocket.send(JSON.stringify(data)),
onmessage: (callback) => websocket.onmessage = callback
};
// 1. 创建连接
const pc = new RTCPeerConnection();
pc.onicecandidate = (e) => signaling.send({ candidate: e.candidate });
pc.ontrack = (e) => document.getElementById('remoteVideo').srcObject = e.streams[0];
// 2. 交换SDP
async function createOffer() {
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({ offer });
}
signaling.onmessage(async ({ data }) => {
const message = JSON.parse(data);
if (message.offer) {
await pc.setRemoteDescription(message.offer);
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
signaling.send({ answer });
} else if (message.answer) {
await pc.setRemoteDescription(message.answer);
} else if (message.candidate) {
await pc.addIceCandidate(message.candidate);
}
});
关键特性与注意事项
- NAT穿透:使用ICE框架(STUN/TURN服务器)解决网络地址转换问题
- 安全机制:强制使用SRTP加密媒体流,仅支持HTTPS或localhost环境
- 兼容性处理:需检测API支持并处理编解码器差异
- 资源管理:及时关闭连接(
pc.close())释放摄像头和网络资源
通过以上步骤,即使在不同网络环境下的两个浏览器也能建立直接通信链路,实现高实时性的音视频通话或数据交换。