前言
时序图
几个关键点
源码分析
Conductor::ConnectToPeer
void Conductor::ConnectToPeer(int peer_id) {***if (InitializePeerConnection()) {peer_id_ = peer_id;peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());***}
PeerConnection::CreateOffer
void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,const RTCOfferAnswerOptions& options) {RTC_DCHECK_RUN_ON(signaling_thread());sdp_handler_->CreateOffer(observer, options);}

可以看到,第一个参数是CreateSessionDescriptionObserver观察者回调,这里输入的是this,说明Conductor也继承了webrtc::CreateSessionDescriptionObserver。
如果调用CreateOffer()方法成功创建了SDP,则WebRTC会回调Conductor对象的OnSuccess()方法,最终通过信令处理模块将创建好的SDP发送给对端;如果创建SDP失败,则会回调Conductor的OnFailure()方法。
Conductor::OnSuccess

void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) {// 创建offer成功后的信息添加到本地 Description内存中peer_connection_->SetLocalDescription(DummySetSessionDescriptionObserver::Create(), desc);// 将创建offer成功后的信息转换为json数据,发送出去到对端std::string sdp;desc->ToString(&sdp);// For loopback test. To save some connecting delay.if (loopback_) {// Replace message type from "offer" to "answer"std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp);peer_connection_->SetRemoteDescription(DummySetSessionDescriptionObserver::Create(),session_description.release());return;}
连接完成后,将发送创建成功的offer消息到对端。对端收到offer后,创建answer消息,并发回到本端,此时本地将调用Conductor::OnMessageFromPeer处理对端消息。
Conductor::OnMessageFromPeer

这里是收到对端消息,然后json解析,判断sdp类型是kOffer则代表是对端发起通信,需要PeerConnection::CreateAnswer 创建answer发回到对端。否则就是自己发起通信,收到的是answer,
void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) {RTC_DCHECK(peer_id_ == peer_id || peer_id_ == -1);RTC_DCHECK(!message.empty());if (!peer_connection_.get()) {RTC_DCHECK(peer_id_ == -1);peer_id_ = peer_id;if (!InitializePeerConnection()) {RTC_LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance";client_->SignOut();return;}} else if (peer_id != peer_id_) {RTC_DCHECK(peer_id_ != -1);RTC_LOG(WARNING)<< "Received a message from unknown peer while already in a ""conversation with a different peer.";return;}// json解析接收到的对端消息Json::Reader reader;Json::Value jmessage;if (!reader.parse(message, jmessage)) {RTC_LOG(WARNING) << "Received unknown message. " << message;return;}std::string type_str;std::string json_object;// 获取信令类型,type_str为answer或者offer,// 如果是本端发起通信,第一次会收到answer类型,后面收到的就是空类型rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName,&type_str);if (!type_str.empty()) { // 类型不为空if (type_str == "offer-loopback") {// This is a loopback call.// Recreate the peerconnection with DTLS disabled.if (!ReinitializePeerConnectionForLoopback()) {RTC_LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance";DeletePeerConnection();client_->SignOut();}return;}// 获取sdp类型absl::optional<webrtc::SdpType> type_maybe =webrtc::SdpTypeFromString(type_str);if (!type_maybe) {RTC_LOG(LS_ERROR) << "Unknown SDP type: " << type_str;return;}webrtc::SdpType type = *type_maybe;// 从json中获取sdp消息std::string sdp;if (!rtc::GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName,&sdp)) {RTC_LOG(WARNING) << "Can't parse received session description message.";return;}// 根据sdp创建SessionDescriptionInterface实例webrtc::SdpParseError error;std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =webrtc::CreateSessionDescription(type, sdp, &error);if (!session_description) {RTC_LOG(WARNING) << "Can't parse received session description message. ""SdpParseError was: "<< error.description;return;}RTC_LOG(INFO) << " Received session description :" << message;// 通过SetRemoteDescription设置对端的sdp消息保存到内存peer_connection_->SetRemoteDescription(DummySetSessionDescriptionObserver::Create(),session_description.release());// 如果是offer消息,则代表是对端发起通信,需要发给对端answerif (type == webrtc::SdpType::kOffer) {peer_connection_->CreateAnswer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());}} else {std::string sdp_mid;int sdp_mlineindex = 0;// 获取sdp信息std::string sdp;if (!rtc::GetStringFromJsonObject(jmessage, kCandidateSdpMidName,&sdp_mid) ||!rtc::GetIntFromJsonObject(jmessage, kCandidateSdpMlineIndexName,&sdp_mlineindex) ||!rtc::GetStringFromJsonObject(jmessage, kCandidateSdpName, &sdp)) {RTC_LOG(WARNING) << "Can't parse received message.";return;}// 根据sdp,创建candidatewebrtc::SdpParseError error;std::unique_ptr<webrtc::IceCandidateInterface> candidate(webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdp, &error));if (!candidate.get()) {RTC_LOG(WARNING) << "Can't parse received candidate message. ""SdpParseError was: "<< error.description;return;}// 添加AddIceCandidateif (!peer_connection_->AddIceCandidate(candidate.get())) {RTC_LOG(WARNING) << "Failed to apply the received candidate";return;}RTC_LOG(INFO) << " Received candidate :" << message;}}
