本文作者:IMWeb jaychen 原文出处:IMWeb社区 未经同意,禁止转载
理论上是可以抛弃stun server,但实际操作上面会有很多限制。
webrtc peer连接过程:
1) 各个peer首先向各自的stun server请求,获取各自的对外IP。(非必须)
2) 各个peer收集自己的ice candidate,这里包括了本机的local地址,及打洞后获取的对外IP,双方交换ice candidate。
3) 各个peer收到对应的ice candidate后,排序后向各个candidate发起stun请求,用stun协议进行连通性测试,通过后择优。
限制:
1,在broswer调用createPeerConnection时,webrtc对ice框架会自动启动,开始收集候选地址。此时若没指明ice的stun server时,则默认选择stun.l.google.com作为stun server。此时国内由于Google被墙,收集到的candidate只是内网的ip。
2,在1不部署自己stun server,无法获取到client的public ip传给server。但client是知道server的public ip的,这个时候可以通过通过发包给server,server可以知道client的public ip。但是在webrtc中,音视频,以及datachanel的candidate信息不单单包括ip 端口外,除了端口号不一致外,还有一些用于连通性检查的“ice-ufrag" and "ice-pwd”属性。webrtc底层在连接建立时,ice协议在检查连通性时会进行校验。
//发送给服务端的本地ICE候选路径
let candidate0={
candidate: "a=candidate:2638051854 1 udp 2122260223 10.70.108.177 60787 typ host generation 0 ufrag dpdk network-id 1 network-cost 10",
sdpMLineIndex: 0,
sdpMid: 'audio'
};
let candidate1={
candidate: "a=candidate:2638051854 1 udp 2122260223 10.70.108.177 60788 typ host generation 0 ufrag dpdk network-id 1 network-cost 10",
sdpMLineIndex: 1,
sdpMid: 'video'
};
let candidate2={
candidate: "a=candidate:477461690 1 udp 1686052607 14.17.22.45 64522 typ srflx raddr 10.70.108.177 rport 60787 generation 0 ufrag dpdk network-id 1 network-cost 10",
sdpMLineIndex: 0,
sdpMid: 'audio'
};
3, stun服务的部署难度不大,且只是用于简单的收发包,逻辑不重。由于浏览器底层的ice协议是webrtc底层的连接方案,此处并没有暴露给开发者,要取出只能通过hack方式。因此去除stun的成本可能比单纯部署stun服务还高,且还有可能会有兼容性问题,对建立连接的成功率没帮助。
具体可参考-互联网工程任务组(IETF)备忘录5245