将获得的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 know
void 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));
}