WebRTC的全称为Web Real-Time Communication,跨平台支持P2P的音视频通信和任意数据的实时传输。适用于视频会议、在线教育、实时聊天、多人游戏和远程协作等场景。
WebRTC的核心组件
getUserMedia:捕获用户的音视频流
主要是调用前端设备的摄像头和麦克风,获取音视频流。可以使用navigator.mediaDevices.getUserMedia()
方法来实现。F12打开控制台,输入以下代码,会弹出一个窗口,询问是否允许访问摄像头和麦克风。
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
// 使用获取到的音视频流
}).catch(error => {
console.error('Error accessing media devices.', error);
});
前端代码获取到的音视频流是一个MediaStream
对象,可以通过video
标签来播放。也可以通过网络传输到其他设备。
RTCPeerConnection:建立点对点连接
建立连接之前,双方需要交换SDP(Session Description Protocol)信息。SDP描述了音视频流的编码格式、分辨率、帧率等信息。
WebRTC采用P2P方式进行音视频通信,RTCPeerConnection是一个API,用于建立和管理点对点连接。可以通过RTCPeerConnection
对象来设置ICE候选者和SDP(Session Description Protocol)信息,也可以通过它创建、保持、监控、关闭连接。
首先,音视频的发起方,需要创建一个RTCPeerConnection
对象,并添加音视频流,然后创建一个offer,设置本地SDP,并发送给远端。
const peerConnection = new RTCPeerConnection();
// 添加音视频流
peerConnection.addStream(stream);
// 创建offer
peerConnection.createOffer().then(offer => {
// 设置本地SDP
return peerConnection.setLocalDescription(offer);
}).then(() => {
// 发送offer给远端
}).catch(error => {
console.error('Error creating offer.', error);
});
远端的接收方,保持监听状态,等待接收offer。接收到offer后,设置远端SDP,然后创建answer,设置本地SDP,并发送给发起方。
peerConnection.setRemoteDescription(new RTCSessionDescription(remoteSDP)).then(() => {
// 创建answer
return peerConnection.createAnswer();
}).then(answer => {
// 设置本地SDP
return peerConnection.setLocalDescription(answer);
}).then(() => {
// 发送answer给远端
}).catch(error => {
console.error('Error creating answer.', error);
});
此时,双方都已经设置了本地和对方的SDP信息,完成了媒体协商,这个过程一般通过信令服务器来完成。也就是双方都不知道对方的IP地址和端口号,只有信令服务器知道。接下来,双方需要建立点对点的连接,那么首先就得知道对方的IP地址和端口号。这个过程是通过ICE(Interactive Connectivity Establishment)来完成的。
ICE:实现内网穿透
ICE最重要的是实现内网穿透。候选人表示一个可能的连接地址,ICE会尝试多种方法来获取可用的IP地址和端口。ICE会在连接建立之前,收集候选者,并通过信令服务器交换候选者信息,最后来选择最佳的连接地址。ICE候选者有三类,按优先级从高到低排序:
- Host候选者:本地网络接口的IP地址和端口号,通常是内网IP地址和端口号。
- SRFLX候选者:通过STUN服务器获取的公网IP地址和端口号,通常是外网IP地址和NAT后的外网端口号。
- Relay候选者:中继服务器的IP地址和端口号,通常是TURN服务器的IP地址和端口号。
ICE用于帮助通信双方在复杂的网络环境中建立连接。主要目标是实现NAT穿透,如果只是局域网通信,可以直接使用Host候选者。关键是要能够找到可用于WebRTC连接的IP地址和端口号,在NAT的环境下,需要用到STUN和TURN服务器,进行辅助的网络穿透。
STUN/TURN:辅助网络穿透
STUN(Session Traversal Utilities for NAT)和TURN(Traversal Using Relays around NAT)是WebRTC中用于NAT穿透的两种协议。STUN服务器用于获取公网IP地址和端口号,TURN服务器用于中继数据流。
在理解STUN和TURN之前,先了解一下NAT,NAT映射私有IP地址到公网IP地址,可能是稳定的,也可能是动态的。如果它是稳定的,我们可以获取到某个私有地址和端口号对应的公网地址和端口号。如果这个端口号不稳定的话,我们只能通过中继服务器来传输数据。
STUN服务:
客户端向STUN服务器发送一个请求,STUN服务器会返回一个响应,响应中包含了客户端的公网IP地址和端口号。如果这个NAT是稳定的映射,那么我们可以直接使用这个公网IP地址和端口号进行通信。网上有公共的STUN服务器可以使用。WebRTC通信双方通过STUN服务器获取到自己的公网IP地址和端口号,然后通过信令服务器把这个信息发送给对方。这样就可以建立点对点的连接了。
TURN服务:
如果无法通过STUN获取稳定的公网IP和端口,那么我们就不能直接使用公网IP地址和端口号进行通信了。这个时候就需要使用TURN服务器。TURN服务器会充当中继服务器,把数据从一个客户端转发到另一个客户端。
WebRTC双方通过TRUN服务器中继通信的流程为:
- 客户端向TURN服务器发送请求,获取公网IP地址和端口号,称为中继地址。并且TURN服务器会和客户端建立一个长连接,以便于后续的数据传输。
- 客户端通过信令服务器把这个公网IP地址和端口号,即ICE候选人发送给对方。
- 对端客户端向TURN服务器发送请求,获取公网IP地址和端口号。
- 对端客户端通过信令服务器把这个公网IP地址和端口号发送给发起方。
- 对端客户端通过TURN服务器进行通信。
- TURN服务器会把某个中继地址收到的数据包,转发给对应的客户端。
总结
WebRTC可以通过简单API,实现音视频通信和数据传输。通信双方通过信令服务器交换SDP和ICE候选者信息,建立点对点连接。ICE用于实现内网穿透,STUN和TURN用于辅助网络穿透。WebRTC的核心组件包括getUserMedia
、RTCPeerConnection
、ICE
、STUN
和TURN
。
WebRTC的应用场景包括视频会议、在线教育、实时聊天、多人游戏和远程协作等。WebRTC的优势在于跨平台支持P2P的音视频通信和任意数据的实时传输。