对等连接入门
最后更新于:2022-04-02 03:29:56
[TOC]
## 概述
- 对等连接是WebRTC规范的一部分,它涉及连接不同计算机上的两个应用程序以使用对等协议进行通信。对等方之间的通信可以是视频,音频或任意二进制数据(对于支持`RTCDataChannel`API的客户端)
- 为了发现两个对等方如何连接,两个客户端都需要提供ICE服务器配置。这可以是STUN服务器,也可以是TURN服务器
## 发信号
```
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
// New message from remote client received
});
signalingChannel.send('Hello!');
```
## 启动对等连接
- 每个对等连接都由`RTCPeerConnection`对象处理
- 创建`RTCPeerConnection`,我们需要创建SDP服务或应答
- 将SDP对象传递到远程对等点称为信令
### 调用方
1. 我们创建一个`RTCPeerConnection`对象
2. 然后调用`createOffer()`创建一个`RTCSessionDescription`对象。
3. 使用`setLocalDescription()`将该会话描述设置为本地描述,然后通过我们的信令通道发送到接收方
```
async function makeCall() {
const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.answer) {
const remoteDesc = new RTCSessionDescription(message.answer);
await peerConnection.setRemoteDescription(remoteDesc);
}
});
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
signalingChannel.send({'offer': offer});
}
```
### 接收方
1. 我们在创建`RTCPeerConnection`实例之前等待收到的报价
2. 我们使用`setRemoteDescription()`设置收到的报价
3. 我们调用`createAnswer()`为收到的报价创建答案
4. 使用`setLocalDescription()`将此答案设置为本地描述,然后通过我们的信令服务器发送到呼叫方
```
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.offer) {
peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
signalingChannel.send({'answer': answer});
}
});
```
一旦两个对等方都设置了本地和远程会话描述,他们便知道了远程对等方的功能。这并不意味着对等方之间的连接已准备就绪。为此,我们需要在每个对等方收集ICE候选者,并(通过信令信道)转移到另一个对等方
### ICE候选人
在两个对等方可以使用WebRTC进行通信之前,他们需要交换连接信息。由于网络状况可能取决于许多因素而变化,因此通常使用外部服务来发现可能的候选对象以连接到对等方。这项服务称为ICE
#### ckle流冰
创建`RTCPeerConnection`对象后,基础框架将使用提供的ICE服务器收集用于建立连接的候选对象(ICE候选对象)。事件`icegatheringstatechange`上`RTCPeerConnection`信号处于什么状态ICE聚会是(`new`,`gathering`或`complete`)
```
// Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
if (event.candidate) {
signalingChannel.send({'new-ice-candidate': event.candidate});
}
});
// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
if (message.iceCandidate) {
try {
await peerConnection.addIceCandidate(message.iceCandidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
}
});
```
### 连接已建立
监听是否连接
```
// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
if (peerConnection.connectionState === 'connected') {
// Peers connected!
}
});
```
';