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

本地Candidate上抛的过程

image.png
需要应用层继承实现回调PeerConnectionObserver,然后后面在PeerConnection::OnIceCandidata的时候会调用observer。

绑定SignalCandidateReady消息

image.png

BasicPortAllocatorSession::OnCandidateReady

image.pngsigslot::signal2&> SignalCandidatesReady;

P2PTransportChannel::AddAllocatorSession(std::unique_ptr session) {

session->SignalCandidatesReady.connect(
this, &P2PTransportChannel::OnCandidatesReady);

}

P2PTransportChannel::OnCandidatesReady

image.png

  1. // A new candidate is available, let listeners know
  2. void P2PTransportChannel::OnCandidatesReady(
  3. PortAllocatorSession* session,
  4. const std::vector<Candidate>& candidates) {
  5. RTC_DCHECK_RUN_ON(network_thread_);
  6. for (size_t i = 0; i < candidates.size(); ++i) {
  7. SignalCandidateGathered(this, candidates[i]);
  8. }
  9. }

// Handles sending and receiving of candidates.
sigslot::signal2 SignalCandidateGathered;

JsepTransportController::CreateDtlsTransport(
const cricket::ContentInfo& content_info,
cricket::IceTransportInternal ice) {
**

dtls->ice_transport()->SignalCandidateGathered.connect(
this, &JsepTransportController::OnTransportCandidateGathered_n);
*
}

JsepTransportController::OnTransportCandidateGathered_n

  1. void JsepTransportController::OnTransportCandidateGathered_n(
  2. cricket::IceTransportInternal* transport,
  3. const cricket::Candidate& candidate) {
  4. // We should never signal peer-reflexive candidates.
  5. if (candidate.type() == cricket::PRFLX_PORT_TYPE) {
  6. RTC_NOTREACHED();
  7. return;
  8. }
  9. signal_ice_candidates_gathered_.Send(
  10. transport->transport_name(), std::vector<cricket::Candidate>{candidate});
  11. }

// [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(callback));
}

—>
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

  1. void PeerConnection::OnTransportControllerCandidatesGathered(
  2. const std::string& transport_name,
  3. const cricket::Candidates& candidates) {
  4. // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
  5. // (not signaling as it currently does), handle appropriately.
  6. int sdp_mline_index;
  7. if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
  8. RTC_LOG(LS_ERROR)
  9. << "OnTransportControllerCandidatesGathered: content name "
  10. << transport_name << " not found";
  11. return;
  12. }
  13. for (cricket::Candidates::const_iterator citer = candidates.begin();
  14. citer != candidates.end(); ++citer) {
  15. // Use transport_name as the candidate media id.
  16. std::unique_ptr<JsepIceCandidate> candidate(
  17. new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
  18. sdp_handler_->AddLocalIceCandidate(candidate.get());
  19. OnIceCandidate(std::move(candidate));
  20. }
  21. }

PeerConnection::OnIceCandidate

  1. void PeerConnection::OnIceCandidate(
  2. std::unique_ptr<IceCandidateInterface> candidate) {
  3. if (IsClosed()) {
  4. return;
  5. }
  6. ReportIceCandidateCollected(candidate->candidate());
  7. Observer()->OnIceCandidate(candidate.get());
  8. }

—>

Conductor::OnIceCandidate

  1. void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
  2. RTC_LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();
  3. // For loopback test. To save some connecting delay.
  4. if (loopback_) {
  5. if (!peer_connection_->AddIceCandidate(candidate)) {
  6. RTC_LOG(WARNING) << "Failed to apply the received candidate";
  7. }
  8. return;
  9. }
  10. Json::StyledWriter writer;
  11. Json::Value jmessage;
  12. jmessage[kCandidateSdpMidName] = candidate->sdp_mid();
  13. jmessage[kCandidateSdpMlineIndexName] = candidate->sdp_mline_index();
  14. std::string sdp;
  15. if (!candidate->ToString(&sdp)) {
  16. RTC_LOG(LS_ERROR) << "Failed to serialize candidate";
  17. return;
  18. }
  19. jmessage[kCandidateSdpName] = sdp;
  20. SendMessage(writer.write(jmessage));
  21. }