前言
WebRTC 是一个实时通信的技术,它提供了一套 API,可以让浏览器实现 P2P 通信,而且不需要额外的插件,这使得 WebRTC 成为了一种非常有前景的技术。在前面几篇文章中,我们已经介绍了 WebRTC 的基本概念和使用,包括音视频通话、屏幕共享、媒体流的处理,还有 WebRTC 与 Tensorflow.js 的结合。从文章的点赞数可以看出来大家对这门技术非常感兴趣。
而这次,我将介绍 WebRTC 的另一个重要功能:P2P 文件传输。
P2P 文件传输
WebRTC 是一种实时通信协议,它可以在浏览器之间进行点对点通信。在 WebRTC 中,不仅可以实现音视频通话,我们还能通过数据通道来传输文本、文件等数据。它可以在浏览器之间进行点对点通信,而且不需要额外的插件,这使得 WebRTC 成为了一种非常有前景的技术。 RTCDataChannel 支持的数据类型也非常多,包括:字符串、Blob、ArrayBuffer…
所以我们可以通过 DataChannel
提供的 API 非常方便的实现点对点的数据传输。而这个特点可以被我们用来传输文件,文本聊天等。。。
实现
- 双向数据通道
- 分段文件传输,支持传输大文件
- 自动生成下载链接
创建数据通道
首先,我们需要创建一个数据通道,用来传输数据。在 WebRTC 中,数据通道是通过 RTCPeerConnection
来创建的,它是一个基于 RTCPeerConnection
的抽象类,它提供了一些 API,可以用来创建数据通道。
// 创建 RTCPeerConnection 对象
var pc = new RTCPeerConnection()
// 创建数据通道
const dataChannel = this.peerConnection.createDataChannel('fileTransfer', {ordered: true, // 保证到达顺序
})
其中 createDataChannel 接收两个参数,第一个是数据通道的名称,第二个是数据通道的配置,这里我们设置了 ordered 为 true,表示保证数据到达顺序。
当然它还有其他的配置,比如:maxPacketLifeTime、maxRetransmits、protocol、negotiated、id。
- ordered:消息的传递是否有序
- maxPacketLifeTime:重传消息失败的最长时间
- maxRetransmits:重传消息失败的最大次数
- protocol:用户自定义的子协议, 默认为空
- negotiated:如果为 true,则会删除另一方数据通道的自动设置
- id:当 negotiated 为 true 时,允许你提供自己的 ID 与 channel 进行绑定
为什么这里我先创建数据通道呢?因为在建立 p2p 连接之后,再建立数据通道,会导致再次触发 negotiationneeded 事件,这样就会导致 ICE 重新协商。 当然,创建数据通道的时机是可以自己根据实际情况控制的,这里我提前建立好,然后它会和媒体流一起进行 ICE 协商。
定义数据通道事件
接下来,我们需要定义数据通道的事件,这里我们需要定义的事件有:
// 监听文件通道状态
// 当文件通道状态发生变化时触发
dataChannel.onopen = (event) => {ElMessage.success('文件通道已打开')console.log('🚀🚀🚀 / event', event)
}
// 当文件通道关闭时触发
dataChannel.onclose = (event) => {ElMessage.warning('文件通道已关闭')
}
// 当文件通道发生错误时触发
dataChannel.onerror = (event) => {ElMessage.error('文件通道发生错误')
}
// 当文件通道收到消息时触发
dataChannel.onmessage = (event) => {// eslint-disable-next-line no-consoleconsole.log('🚀🚀🚀 / event', event)
}
WebRTC 建立 P2P 连接
import io from 'socket