WebRTC如何实现平滑的网络切换

在某些场景下,我们希望手动切换网络,如WiFi切换到4G。网络的切换导致原本的传输链路中断,由于WebRTC采用基于ICE协议栈的P2P传输模式,传输链路的新建需要进行新一轮的ICE交互。

传统方式下,ICE交互的完成依赖于Offer/Answer机制,双方交换candidates以实现点对点连接。

ICE candidates需要双端配合完成。本端会将本地网卡地址、STUN服务观察到的本地真实地址、TURN服务为本地分配的Relay地址加入candidate列表,并创建相应SDP通过Offer/Answer流程进行交互。双端接收到彼此的candidates后会进行连通性检查,并为每个candidate添加优先级(local_candidate().priority()),最终采用优先级较高的candidate作为真实链接的IP地址。

上述方式双端只会在收集完成candidates后再进行连通性检查,由于收集candidates需要一定时间,使得ICE流程耗时较长,最终表现为WebRTC 建立P2P连接的过程十分缓慢。

为解决这一问题,RFC 8838提出了“Trickle ICE”,该方案将gather candidate与check connectivity两个步骤同时进行,大大降低了连接建立的耗时。

Vanilla ICE vs Trickle ICE

现版本WebRTC默认配置开启trickle选项(ICE_OPTION_TRICKLE),初次连接的建立速度很快。当然,在此之上我们还可以通过以下配置来加快candidates的收集:

1.不使用IPV6网络
peer_conn_config.disable_ipv6 = true;

2.不使用TCP进行媒体传输
peer_conn_config.tcp_candidate_policy = webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled;

回归正题,我们希望在WebRTC通讯过程中实现平滑的网络切换,而网络切换意味着IP地址更换。按照上述ICE流程,我们需要重新收集本地candidates,并通过SDP交互完成连接的建立。本地环境下实测,从CreateOffer到视频流恢复,中间因ICE重连接引发的视频卡顿在3秒左右。能否进行优化?

走读源码发现RTCOfferAnswerOptions中有ice_restart配置项,默认false,但意义不明。

参考RFC5245,ICE restart机制能够保证在restart过程中,媒体数据可以继续通过之前验证有效的candidate pair进行传输,这个机制也是我们这篇文章的最终目的,实现平滑的网络切换。

本地环境下实测,将ice_restart置为true后进行SDP交互。观察发现视频仍会卡顿,且卡顿时间并未缩短。继续走读代码,发现RTCConfiguration中有continual_gathering_policy配置项,默认GATHER_ONCE,含义如下。

continual_gathering_policy

该配置项设置为GATHER_CONTINUALLY时,允许WebRTC在通讯过程中持续收集candidates,一旦网络状况发生改变,将使用当前有效的candidate pair取代失效的candidate pair进行数据传输。本地环境下实测,禁用一个网卡时,WebRTC的数据传输会迅速调整到另一块网卡,视频流几乎没有卡顿出现。

结合上述ice_restart配置项,continual_gathering_policy实现了WebRTC内部自动化的网络平滑切换,如果此时开启ice_restart并重新进行SDP交互,整个连接的建立流程几乎也是无缝的。ice_restart配置项为主动切换网络提供了可能,例如在SDP交互过程中删除某个candidate,来取代手动禁用网卡。

原文 WebRTC如何实现平滑的网络切换 - 知乎 

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

猜你喜欢

转载自blog.csdn.net/yinshipin007/article/details/132460268