将获得的Candidate上抛给应用层,就是为了通信双方交换Candidate,然后获取到对端的candidate,然后建立连接。
本地Candidate上抛的过程

需要应用层继承实现回调PeerConnectionObserver,然后后面在PeerConnection::OnIceCandidata的时候会调用observer。
绑定SignalCandidateReady消息
BasicPortAllocatorSession::OnCandidateReady
sigslot::signal2
P2PTransportChannel::AddAllocatorSession(std::unique_ptr
session->SignalCandidatesReady.connect(
this, &P2PTransportChannel::OnCandidatesReady);
}
P2PTransportChannel::OnCandidatesReady

// A new candidate is available, let listeners knowvoid P2PTransportChannel::OnCandidatesReady(PortAllocatorSession* session,const std::vector<Candidate>& candidates) {RTC_DCHECK_RUN_ON(network_thread_);for (size_t i = 0; i < candidates.size(); ++i) {SignalCandidateGathered(this, candidates[i]);}}
// Handles sending and receiving of candidates.
sigslot::signal2
JsepTransportController::CreateDtlsTransport(
const cricket::ContentInfo& content_info,
cricket::IceTransportInternal ice) {
**
dtls->ice_transport()->SignalCandidateGathered.connect(
this, &JsepTransportController::OnTransportCandidateGathered_n);
*
}
JsepTransportController::OnTransportCandidateGathered_n
void JsepTransportController::OnTransportCandidateGathered_n(cricket::IceTransportInternal* transport,const cricket::Candidate& candidate) {// We should never signal peer-reflexive candidates.if (candidate.type() == cricket::PRFLX_PORT_TYPE) {RTC_NOTREACHED();return;}signal_ice_candidates_gathered_.Send(transport->transport_name(), std::vector<cricket::Candidate>{candidate});}
// [mid, candidates]
CallbackList
signalice_candidates_gathered RTCGUARDED_BY(network_thread);
// F: void(const std::string&, const std::vector
template
void SubscribeIceCandidateGathered(F&& callback) {
RTCDCHECK_RUN_ON(network_thread);
signalice_candidates_gathered.AddReceiver(std::forward
}
—>
PeerConnection::InitializeTransportControllern{
*
transport_controller->SubscribeIceCandidateGathered(
this {
RTCDCHECK_RUN_ON(network_thread());
signaling_thread()->PostTask(
ToQueuedTask(signaling_thread_safety.flag(),
this, t = transport, c = candidates {
RTC_DCHECK_RUN_ON(signaling_thread());
OnTransportControllerCandidatesGathered(t, c);
}));
});
*
}
PeerConnection::OnTransportControllerCandidatesGathered
void PeerConnection::OnTransportControllerCandidatesGathered(const std::string& transport_name,const cricket::Candidates& candidates) {// TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread// (not signaling as it currently does), handle appropriately.int sdp_mline_index;if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {RTC_LOG(LS_ERROR)<< "OnTransportControllerCandidatesGathered: content name "<< transport_name << " not found";return;}for (cricket::Candidates::const_iterator citer = candidates.begin();citer != candidates.end(); ++citer) {// Use transport_name as the candidate media id.std::unique_ptr<JsepIceCandidate> candidate(new JsepIceCandidate(transport_name, sdp_mline_index, *citer));sdp_handler_->AddLocalIceCandidate(candidate.get());OnIceCandidate(std::move(candidate));}}
PeerConnection::OnIceCandidate
void PeerConnection::OnIceCandidate(std::unique_ptr<IceCandidateInterface> candidate) {if (IsClosed()) {return;}ReportIceCandidateCollected(candidate->candidate());Observer()->OnIceCandidate(candidate.get());}
Conductor::OnIceCandidate
void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {RTC_LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();// For loopback test. To save some connecting delay.if (loopback_) {if (!peer_connection_->AddIceCandidate(candidate)) {RTC_LOG(WARNING) << "Failed to apply the received candidate";}return;}Json::StyledWriter writer;Json::Value jmessage;jmessage[kCandidateSdpMidName] = candidate->sdp_mid();jmessage[kCandidateSdpMlineIndexName] = candidate->sdp_mline_index();std::string sdp;if (!candidate->ToString(&sdp)) {RTC_LOG(LS_ERROR) << "Failed to serialize candidate";return;}jmessage[kCandidateSdpName] = sdp;SendMessage(writer.write(jmessage));}
