阅读 904

WebRTC实现P2P文件传输

概述

本文讲的是利用WebRTC中的RTCPeerConnection的能力如何实现P2P通信的,在文末还有demo实现了P2P传输文件的应用,P2P传输文件的好处就是可以在同一内网的两台机器直接通过内网传输。

本文涉及的技术点会有点多,我会先从介绍WebRTC和P2P开始,然后围绕WebRTC建立P2P连接的过程了解所有的具体内容。

WebRTC简介

webrtc是为浏览器提供实现实时音视频通信能力的Api,分为Network Stream API、 RTCPeerConnection、Peer-to-peer Data API三类

Network Stream API

  • MediaStream:MediaStream用来表示一个媒体数据流。
  • MediaStreamTrack在浏览器中表示一个媒体源。

RTCPeerConnection

  • RTCPeerConnection: 一个RTCPeerConnection对象允许用户在两个浏览器之间直接通讯。
  • RTCIceCandidate :表示一个ICE协议的候选者。
  • RTCIceServer:表示一个ICE Server。

Peer-to-peer Data API

  • DataChannel:数据通道( DataChannel)接口表示一个在两个节点之间的双向的数据通道 。

WebRTC内置了许多音视频处理引擎和编码器以及网络协议,有些可以直接在API层使用,而且WebRTC是开源的,所以我们也可以直接使用WebRTC的底层核心技术,比如可以从中提取 3A(AEC、AGC、ANC)的算法用到自己的项目中,还有网络带宽的评估、平滑处理、各种网络协议的实现在 WebRTC 中真是应有尽有,感兴趣的可了解WebRTC的源码webrtc.googlesource.com/src

P2P网络

专业名称叫对等网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构,是对等计算模型在应用层形成的一种组网或网络形式。在P2P网络环境中,彼此连接的多台计算机之间都处于对等的地位,无主从之分,每个节点既充当服务器,为其他节点提供服务,同时也享用其他节点提供的服务。

对等网络是对分布式概念的成功拓展,它将传统方式下的服务器负担分配到网络中的每一节点上,每一节点都将承担有限的存储与计算任务,加入到网络中的节点越多,节点贡献的资源也就越多,其服务质量也就越高。

WebRTC建立P2P连接

在两个客户端之间建立点对点连接需要先进行媒体协商和网络协商来确定两端的数据兼容以及网络互通情况

媒体协商

彼此要了解对方支持的媒体格式

比如:Peer-A端可支持VP8、H264多种编码格式,而Peer-B端支持VP9、H264,要保证二端都正确的编解码,最简单的办法就是取它们的交集H264 在WebRTC中,参与视频通讯的双方必须先交换SDP信息,保证双方都能解析彼此的数据,而交换SDP的过程,也称为"媒体协商"。

SDP全称是Session Description Protocol,翻译过来就是描述会话的协议。主要用于两个会话实体之间的媒体协商,主要是为了解决参与会话的各成员之间能力不对等的问题,如果参加本次通话的成员都支持高质量的通话,但是我们没有去进行协议,为了兼容性,使用的都是普通质量的通话格式,这样就很浪费资源了。

网络协商

彼此要了解对方的网络情况,这样才有可能找到一条相互通讯的链路,网络协商主要就是探测两端的网络类型,在WebRTC通过STUN/TURN服务器确定网络类型之后就会收集ICEcandidate来确定建立哪种类型的连接。

STUN

STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT(或多重NAT)后的客户 端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于 NAT路由器之后的主机之间建立UDP通信。这个过程俗称NAT打洞或NAT穿越,

STUN服务器打洞过程:

TURN

TURN的全称为Traversal Using Relay NAT,即通过Relay方式穿越NAT,客户端通过发送Allocate请求给STUN服务器,从而让STUN服务器为A用户开启一个relay端口,可以看做是A的公网代理端口,TURN服务器就像代理服务器一样转发访问A用户的数据。

ICEcandidate

ICEcandidate用来表示 WebRTC 与远端通信时使用的协议、IP 地址和端口,其中最主要的ICEcandidate的类型,分为下列三种类型: ● host 类型:本机内网,内网P2P连接 ● srflx 类型:本机 NAT 映射后的外网,非对称型NAT网络环境,外网P2P连接 ● relay 类型:一般是对称性NAT网络,需要走TURN中继服务器,无法建立P2P连接 其实 ICE 就是上面所讲的获取各种类型 Candidate 的过程,也就是:在本机收集所有的 host 类型的 Candidate,通过 STUN 协议收集 srflx 类型的 Candidate,使用 TURN 协议收集 relay 类型的 Candidate。

如果想确定自己浏览器里的webrtc客户端建立的是什么类型,可以通过chrome://webrtc-internals/查看

信令服务器

两端需要交换彼此的SDP和ICEcandidate信息,可以通过一个简单的websocket服务器来拿到对方的信令,信令服务器也可以做心跳检查确保对方是在线状态。

点对点连接

理解了媒体协商和网络协商之后,我们如何用WebRTC来实现点对点连接呢?

WebRTC实现流程如下:

demo体验

peer.codeasily.net/

本demo实现了内网P2P文件传输,文件会分片传输,信令服务器是用自己的廉价服务器搭的,demo版体验不会太好,望体谅,源码就不放了,后续可能会封装库开源出来

进入demo后等待分配uuid,分配完成后点击copy按钮可以复制uuid发送给对方

image-20210118203601565

填入对方的uuid,点击connect按钮即可建立连接

image-20210118203721082

如果建立连接完成会看到下面的界面,如果一直在转的话尝试刷新重试

image-20210118203838491

根据内容提示左边的红色区域是发送方选择文件,然后点Send按钮即可发送,而右边的蓝色区域就是接收方,接收方会收到对方的文件

遇到的问题

在实现P2P传输的过程中遇到以下几个问题:

  1. WebRTC的dataChannel传输的是udp包,传输并发量大的情况下容易丢包;

解决办法是控制并发数量,用一个并发队列,并在对方每收到一个分片时发送一个received信令,发送方就可以从并发池里释放一个位置继续添加发送任务

  1. 新版chrome内核已经无法获取明确的本地ip,而是一个指向本机ip的mDNS,导致在相同内网的不同设备无法走内网传输;

mDNS是一种内网的一种dns域名协议,当有一台新设备进入局域网会先给自己定一个指向本机ip的mDNS域名,并广播给内网所有机子并记录起来,域名解析分布在每一台机子中,mDNS的缺点很明显,在内网广播消耗一定的内网资源,内网机器连接也会多一层dns解析,mDNS的兼容性还不太好。 而WebRTC只是因为被诟病因为获取真实ip而采用了mDNS这种方式提高安全性。

文章分类
前端
文章标签