前言
这个星期碰到公司同事有项目是需要做对讲功能,但听说一直以来都是调用的第三方SDK。听到这类需求首先想到是webRTC相关的开发。
虽然之前有过一段时间想去了解,但碍于webRTC里出现的概念对于传统的web开发来说比较陌生以及也没有实际的开发需要,所以中途都放弃了。
但未来可能会有这种需求,那就借此机会来稍微弄清webRTC是建立P2P的连接的机制。
正文
流程图
以下是根据peerjs源码,梳理的webRTC在建立连接时的流程图:
flowchart TD step1[创建RTCPeerConnection] step2[peerConnection创建DataChannel] step3[peerConnection创建offer] step4[把offer设为localDescription] step5[触发icecandidate] step6[把candidate通过socket发送给peer] step7[把offer通过socket发送给peer] step8[peer接收offer] step9[peer把offer里的sdp设为remoteDescription] step10[peer创建answer] step11[peer把answer设为localDescription] step12[peer把answer通过socket发送回来] step13[peer进行addIceCandidate] step14[把peer的answer设为remoteDescription] step15[peer触发icecandidate] step16[peer把candidate通过socket发送回来] step17[进行addIceCandiate] step1-->step2 step2-->step3 step3-->step4 step4--2-->step5 step5-->step6 step4--1-->step7 step7-->step8 step8-->step9 step9-->step10 step10-->step11 step11--1-->step12 step11--2-->step15 step15-->step16 step16-->step17 step12-->step14 step6-->step13
术语:
transport address在RFC文档中指代ip地址和portSTUN(Session Traversal Utilities for NAT)服务器的主要作用是帮助client获取其对应的经NAT转换后的public transport addressTURN(Traversal Using Relays Around NAT)服务器的主要作用是给peerA,分配一个relayed transport address,让peerB通过发送数据到这个地址后,TURN服务器再转发给peerB。TURN可以解决STUN无法处理的Symmetric NAT类型。Symmetric NAT是指NAT会因请求方的transport address或接收方的transport address不同,而给请求方映射不同的public transport address。因为目标地址不一,所以peerB不能使用与STUN服务器收到的server-reflexive transport address相同的地址与peerA通信。
需要signaling服务的原因
由于RTCConnection未建立前并不知道对方的transport address,所以需要开发者先通过任意signaling服务作中介(服务的实现方式不作限定,常见的是通过websocket)来交换各自session description和ice candidate。
sd格式
session description包含己方将要传输的媒体信息(地址、端口、格式等),是一个多行key=value格式的文本。
STUN/TURN服务器的作用
在setLocalDescription后,会请求STUN/TURN服务器来获得peer可以直接通信的transport address,生成candidate的配置后触发icecandidate事件,。把candiate通过signaliing服务发给peer,让对方把这个连接候选方式,添加到peerConnection中。
candidate生成结束
当某一轮的candidate生成完毕后,icecandidate事件会回调一个空的candiate来标志生成完毕,如果连接建立成功iceconnectionstatechange,peerConnection的iceConnectionState会变为connected。
candidate的类型:
1.host:直连,peer的真实地址
2.srflx:server-reflexive,发送STUN Binding Request到STUN服务器后,经NAT转换过的public地址
3.prflx:peer-flexive,发送STUN Binding Request到peer后,从peer获得的经NAT转换过的public地址
4.relay:TURN服务的中继地址
webRTC会按规则选取最优的candidate进行连接。
总结
本文只是简单地梳理了webRTC建立连接过程发生的事情,但也可以看到其实webRTC(先不论存在relay的情况)跟一般的request/response的模式差别不太大,服务方都会通过server-reflexive的transport address传数据给client,可能因为使用的是udp,实时性会更好些。所以如果只是单方面的视频推流,感觉是不太需要用到webRTC的,webRTC的主要使用场景应该是数据实时互传方面的。