H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\p2p\base\p2p_transport_channel.cc
你只能裁你同一个network上的connection,多主机上每个network最终都决胜一个最优的connection,最终的网路调整就在每个网卡的最优connection切换。
- 对于Controlling端,每次更新UpdateState后(Connection状态发生变动必然会触发UpdateState),就会面临裁剪.
- 对于Controlled端,只有当选出了Selected_Connection后,并nominated后才会进行裁剪.
https://zhuanlan.zhihu.com/p/443154955
SortConnectionsAndUpdateState

// Sort the available connections to find the best one. We also monitor// the number of available connections and the current state.void P2PTransportChannel::SortConnectionsAndUpdateState(IceControllerEvent reason_to_sort) {RTC_DCHECK_RUN_ON(network_thread_);// Make sure the connection states are up-to-date since this affects how they// will be sorted.UpdateConnectionStates();// Any changes after this point will require a re-sort.sort_dirty_ = false;// If necessary, switch to the new choice. Note that |top_connection| doesn't// have to be writable to become the selected connection although it will// have higher priority if it is writable.MaybeSwitchSelectedConnection(reason_to_sort, ice_controller_->SortAndSwitchConnection(reason_to_sort));// The controlled side can prune only if the selected connection has been// nominated because otherwise it may prune the connection that will be// selected by the controlling side.// TODO(honghaiz): This is not enough to prevent a connection from being// pruned too early because with aggressive nomination, the controlling side// will nominate every connection until it becomes writable.if (ice_role_ == ICEROLE_CONTROLLING ||(selected_connection_ && selected_connection_->nominated())) {PruneConnections();}// Check if all connections are timedout.bool all_connections_timedout = true;for (const Connection* conn : connections()) {if (conn->write_state() != Connection::STATE_WRITE_TIMEOUT) {all_connections_timedout = false;break;}}// Now update the writable state of the channel with the information we have// so far.if (all_connections_timedout) {HandleAllTimedOut();}// Update the state of this channel.UpdateState();// Also possibly start pinging.// We could start pinging if:// * The first connection was created.// * ICE credentials were provided.// * A TCP connection became connected.MaybeStartPinging();}
P2PTransportChannel::PruneConnections

void P2PTransportChannel::PruneConnections() {RTC_DCHECK_RUN_ON(network_thread_);std::vector<const Connection*> connections_to_prune =ice_controller_->PruneConnections();for (const Connection* conn : connections_to_prune) {FromIceController(conn)->Prune();}}
PruneConnections
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\p2p\base\basic_ice_controller.cc
获取可以裁剪的connections
std::vector<const Connection*> BasicIceController::PruneConnections() {// We can prune any connection for which there is a connected, writable// connection on the same network with better or equal priority. We leave// those with better priority just in case they become writable later (at// which point, we would prune out the current selected connection). We leave// connections on other networks because they may not be using the same// resources and they may represent very distinct paths over which we can// switch. If |best_conn_on_network| is not connected, we may be reconnecting// a TCP connection and should not prune connections in this network.// See the big comment in CompareConnectionStates.//// An exception is made for connections on an "any address" network, meaning// not bound to any specific network interface. We don't want to keep one of// these alive as a backup, since it could be using the same network// interface as the higher-priority, selected candidate pair.std::vector<const Connection*> connections_to_prune;auto best_connection_by_network = GetBestConnectionByNetwork();for (const Connection* conn : connections_) {const Connection* best_conn = selected_connection_;if (!rtc::IPIsAny(conn->network()->ip())) {// If the connection is bound to a specific network interface (not an// "any address" network), compare it against the best connection for// that network interface rather than the best connection overall. This// ensures that at least one connection per network will be left// unpruned.best_conn = best_connection_by_network[conn->network()];}// Do not prune connections if the connection being compared against is// weak. Otherwise, it may delete connections prematurely.if (best_conn && conn != best_conn && !best_conn->weak() &&CompareConnectionCandidates(best_conn, conn) >= 0) {connections_to_prune.push_back(conn);}}return connections_to_prune;}
BasicIceController::GetBestConnectionByNetwork
遍历所有连接的connections_,获取每个网络的最优connection。

std::map<const rtc::Network*, const Connection*>BasicIceController::GetBestConnectionByNetwork() const {// |connections_| has been sorted, so the first one in the list on a given// network is the best connection on the network, except that the selected// connection is always the best connection on the network.std::map<const rtc::Network*, const Connection*> best_connection_by_network;if (selected_connection_) {best_connection_by_network[selected_connection_->network()] =selected_connection_;}// TODO(honghaiz): Need to update this if |connections_| are not sorted.for (const Connection* conn : connections_) {const rtc::Network* network = conn->network();// This only inserts when the network does not exist in the map.best_connection_by_network.insert(std::make_pair(network, conn));}return best_connection_by_network;}
Connection::Prune

此时,裁剪的connection已经被标记了,然后等待这些资源被释放掉。
