WebRTC全称为Web Real-Time Communication,是浏览器内置的原生实时通信技术,允许两个浏览器之间直接建立点对点连接,传输音视频流和任意数据,不需要经过中间服务器转发媒体内容,延迟低且兼容性好。

WebRTC实时通信的核心概念
要实现WebRTC实时通信,首先需要理解几个核心对象的作用:
- RTCPeerConnection:负责管理点对点连接的整个生命周期,包括媒体流协商、ICE候选收集、连接状态维护等。
- MediaStream:表示媒体流,包含音频轨道和视频轨道,可以通过浏览器API获取本地摄像头、麦克风的流,也可以接收远程端传来的流。
- RTCDataChannel:用于在点对点连接上传输任意数据,支持可靠和不可靠两种传输模式,适合传输文本、文件等内容。
- 信令服务器:WebRTC本身不提供信令传输能力,需要开发者自己搭建信令服务器,用于交换连接双方的SDP描述和ICE候选信息,常见的信令协议可以用WebSocket实现。
WebRTC实时通信的实现步骤
1. 获取本地媒体流
首先通过navigator.mediaDevices.getUserMedia方法获取本地的摄像头和麦克风媒体流,这是音视频通信的基础。
// 获取本地音视频流
async function getLocalStream() {
try {
// 请求摄像头和麦克风权限,获取媒体流
const localStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
// 将本地流显示在video标签中
const localVideo = document.getElementById('localVideo');
localVideo.srcObject = localStream;
return localStream;
} catch (error) {
console.error('获取本地媒体流失败:', error);
}
}
2. 创建RTCPeerConnection实例
初始化连接对象,并绑定相关的事件监听,处理远程流到达、ICE候选收集等逻辑。
// 创建连接实例
function createPeerConnection(localStream, signalingServer) {
// 配置ICE服务器,用于穿透NAT,这里使用公共STUN服务器
const iceServers = [{
urls: 'stun:stun.l.google.com:19302'
}];
const peerConnection = new RTCPeerConnection({ iceServers });
// 将本地流的所有轨道添加到连接中
localStream.getTracks().forEach(track => {
peerConnection.addTrack(track, localStream);
});
// 监听远程流到达事件,将远程流显示到页面
peerConnection.ontrack = (event) => {
const remoteVideo = document.getElementById('remoteVideo');
if (remoteVideo.srcObject !== event.streams[0]) {
remoteVideo.srcObject = event.streams[0];
}
};
// 收集到ICE候选时,通过信令服务器发送给对端
peerConnection.onicecandidate = (event) => {
if (event.candidate) {
signalingServer.send(JSON.stringify({
type: 'ice_candidate',
candidate: event.candidate
}));
}
};
return peerConnection;
}
3. 信令交换流程
WebRTC连接需要双方交换SDP(会话描述协议)信息和ICE候选,这部分需要通过信令服务器完成,以下是发起端和接收端的核心逻辑:
发起端逻辑
// 发起端创建Offer并发送
async function initOffer(peerConnection, signalingServer) {
// 创建Offer类型的SDP描述
const offer = await peerConnection.createOffer();
// 设置本地SDP描述
await peerConnection.setLocalDescription(offer);
// 通过信令服务器发送Offer给接收端
signalingServer.send(JSON.stringify({
type: 'offer',
sdp: peerConnection.localDescription
}));
}
接收端逻辑
// 接收端处理Offer并创建Answer
async function handleOffer(offerSdp, peerConnection, signalingServer) {
// 设置远程SDP描述
await peerConnection.setRemoteDescription(new RTCSessionDescription(offerSdp));
// 创建Answer类型的SDP描述
const answer = await peerConnection.createAnswer();
// 设置本地SDP描述
await peerConnection.setLocalDescription(answer);
// 通过信令服务器发送Answer给发起端
signalingServer.send(JSON.stringify({
type: 'answer',
sdp: peerConnection.localDescription
}));
}
// 发起端处理Answer
async function handleAnswer(answerSdp, peerConnection) {
await peerConnection.setRemoteDescription(new RTCSessionDescription(answerSdp));
}
// 处理对端发来的ICE候选
async function handleIceCandidate(candidate, peerConnection) {
await peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
}
4. 建立数据通道(可选)
如果需要传输文本、文件等非媒体数据,可以创建RTCDataChannel,以下是数据通道的使用示例:
// 创建数据通道
function createDataChannel(peerConnection) {
const dataChannel = peerConnection.createDataChannel('messageChannel');
// 监听数据通道打开事件
dataChannel.onopen = () => {
console.log('数据通道已打开');
// 发送测试消息
dataChannel.send('Hello WebRTC');
};
// 监听收到消息事件
dataChannel.onmessage = (event) => {
console.log('收到远程消息:', event.data);
};
return dataChannel;
}
// 接收端监听数据通道创建事件
peerConnection.ondatachannel = (event) => {
const dataChannel = event.channel;
dataChannel.onmessage = (e) => {
console.log('收到数据通道消息:', e.data);
};
};
完整示例页面结构
以下是包含本地和远程视频展示、连接触发按钮的简单页面结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>WebRTC实时通信示例</title>
<style>
.video-container {
display: flex;
gap: 20px;
}
video {
width: 400px;
height: 300px;
border: 1px solid #ccc;
}
button {
margin: 10px 5px;
padding: 8px 16px;
}
</style>
</head>
<body>
<div class="video-container">
<div>
<h3>本地视频</h3>
<video id="localVideo" autoplay muted></video>
</div>
<div>
<h3>远程视频</h3>
<video id="remoteVideo" autoplay></video>
</div>
</div>
<div>
<button id="startBtn">开始获取本地流</button>
<button id="callBtn" disabled>发起通话</button>
<button id="hangupBtn" disabled>挂断通话</button>
</div>
<script src="webrtc.js"></script>
</body>
</html>
常见问题与注意事项
- WebRTC需要在HTTPS环境下运行,本地localhost环境可以例外,生产环境必须配置SSL证书。
- STUN/TURN服务器用于解决NAT穿透问题,如果双方都在同一个局域网内,公共STUN服务器可能足够,跨网络场景建议部署自己的TURN服务器。
- 信令服务器的实现可以根据需求选择,WebSocket是最常用的方案,也可以用HTTP轮询等方式,只要能完成SDP和ICE候选的交换即可。
- 不同浏览器的WebRTC实现可能存在细微差异,开发时建议做好兼容性处理,可以通过检测RTCPeerConnection是否存在来判断浏览器是否支持WebRTC。
WebRTCJavaScript实时通信peer_connection修改时间:2026-07-08 04:51:37