前言

image.png
image.png

代码分析

SdpOfferAnswerHandler::DoSetLocalDescription
->
JsepTransportController::MaybeStartGathering
image.png

  1. SdpOfferAnswerHandler::DoSetLocalDescription {
  2. ***
  3. // MaybeStartGathering needs to be called after informing the observer so that
  4. // we don't signal any candidates before signaling that SetLocalDescription
  5. // completed.
  6. transport_controller()->MaybeStartGathering();
  7. }

JsepTransportController::MaybeStartGathering

  1. void JsepTransportController::MaybeStartGathering() {
  2. if (!network_thread_->IsCurrent()) {
  3. network_thread_->Invoke<void>(RTC_FROM_HERE,
  4. [&] { MaybeStartGathering(); });
  5. return;
  6. }
  7. for (auto& dtls : GetDtlsTransports()) {
  8. dtls->ice_transport()->MaybeStartGathering();
  9. }
  10. }

P2PTransportChannel::MaybeStartGathering

  1. void P2PTransportChannel::MaybeStartGathering() {
  2. RTC_DCHECK_RUN_ON(network_thread_);
  3. // 首先会判断ufrag和pwd是否为空
  4. if (ice_parameters_.ufrag.empty() || ice_parameters_.pwd.empty()) {
  5. RTC_LOG(LS_ERROR)
  6. << "Cannot gather candidates because ICE parameters are empty"
  7. " ufrag: "
  8. << ice_parameters_.ufrag << " pwd: " << ice_parameters_.pwd;
  9. return;
  10. }
  11. // Start gathering if we never started before, or if an ICE restart occurred.
  12. // 新启动一个收集。或者重启收集
  13. if (allocator_sessions_.empty() ||
  14. IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(),
  15. allocator_sessions_.back()->ice_pwd(),
  16. ice_parameters_.ufrag, ice_parameters_.pwd)) {
  17. ***
  18. // Time for a new allocator.
  19. // 获取一个pooled_session ,连接池
  20. std::unique_ptr<PortAllocatorSession> pooled_session =
  21. allocator_->TakePooledSession(transport_name(), component(),
  22. ice_parameters_.ufrag,
  23. ice_parameters_.pwd);
  24. if (pooled_session) {
  25. AddAllocatorSession(std::move(pooled_session));
  26. PortAllocatorSession* raw_pooled_session =
  27. allocator_sessions_.back().get();
  28. // Process the pooled session's existing candidates/ports, if they exist.
  29. OnCandidatesReady(raw_pooled_session,
  30. raw_pooled_session->ReadyCandidates());
  31. for (PortInterface* port : allocator_sessions_.back()->ReadyPorts()) {
  32. OnPortReady(raw_pooled_session, port);
  33. }
  34. if (allocator_sessions_.back()->CandidatesAllocationDone()) {
  35. OnCandidatesAllocationDone(raw_pooled_session);
  36. }
  37. } else {
  38. // 添加一个收集器
  39. AddAllocatorSession(allocator_->CreateSession(
  40. transport_name(), component(), ice_parameters_.ufrag,
  41. ice_parameters_.pwd));
  42. allocator_sessions_.back()->StartGettingPorts();
  43. }
  44. }
  45. }

BasicPortAllocatorSession::StartGettingPorts

image.png

  1. void BasicPortAllocatorSession::StartGettingPorts() {
  2. RTC_DCHECK_RUN_ON(network_thread_);
  3. state_ = SessionState::GATHERING;
  4. if (!socket_factory_) {
  5. owned_socket_factory_.reset(
  6. new rtc::BasicPacketSocketFactory(network_thread_));
  7. socket_factory_ = owned_socket_factory_.get();
  8. }
  9. // 向网络线程发送一个任务,根据参数,此时当前类的OnMessage会收到MSG_CONFIG_START
  10. network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START);
  11. ***
  12. }

OnMessage处理线程消息

  1. void BasicPortAllocatorSession::OnMessage(rtc::Message* message) {
  2. switch (message->message_id) {
  3. case MSG_CONFIG_START:
  4. GetPortConfigurations();
  5. break;
  6. case MSG_CONFIG_READY:
  7. OnConfigReady(static_cast<PortConfiguration*>(message->pdata));
  8. break;
  9. case MSG_ALLOCATE:
  10. OnAllocate();
  11. break;
  12. case MSG_SEQUENCEOBJECTS_CREATED:
  13. OnAllocationSequenceObjectsCreated();
  14. break;
  15. case MSG_CONFIG_STOP:
  16. OnConfigStop();
  17. break;
  18. default:
  19. RTC_NOTREACHED();
  20. }
  21. }

BasicPortAllocatorSession::GetPortConfiguration

  1. void BasicPortAllocatorSession::GetPortConfigurations() {
  2. RTC_DCHECK_RUN_ON(network_thread_);
  3. PortConfiguration* config =
  4. new PortConfiguration(allocator_->stun_servers(), username(), password());
  5. for (const RelayServerConfig& turn_server : allocator_->turn_servers()) {
  6. config->AddRelay(turn_server);
  7. }
  8. ConfigReady(config);
  9. }
  10. void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
  11. RTC_DCHECK_RUN_ON(network_thread_);
  12. // 向网络线程发送MSG_CONFIG_READY信息
  13. network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_READY, config);
  14. }
  15. void BasicPortAllocatorSession::OnMessage(rtc::Message* message) {
  16. switch (message->message_id) {
  17. ***
  18. case MSG_CONFIG_READY:
  19. OnConfigReady(static_cast<PortConfiguration*>(message->pdata));
  20. break;
  21. ***
  22. }
  23. }
  24. // Adds a configuration to the list.
  25. void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
  26. RTC_DCHECK_RUN_ON(network_thread_);
  27. if (config) {
  28. configs_.push_back(config);
  29. }
  30. AllocatePorts();
  31. }