webrtc-m79-peerconnection_client-收集 relay candidate_01

使用标准的 TURN 协议。TURN 协议是 STUN 协议的一个扩展,它利用一个中继服务器,使得无法建立 P2P 连接的客户端(NAT 严格限制导致)也能实现通讯。

TURN 协议的工作流程如下:

客户端发送 Allocate request 到 server,server 返回 401 未授权错误(带有 realm 和 nonce),客户端再发送带上认证信息的 
Allocate request,server 返回成功分配的 relay address。分配成功后,客户端需要通过发送机制(Send Mechanism)或信道机制(Channels)
在 server 上配置和其他 peer 的转发信息。此外 allocation 和 channel 都需要保活。

WebRTC 使用的是信道机制,因为这一机制的数据开销更低。
收集 TURN relay candidate 时也可以复用收集 host candidate 时创建的 socket 对象,这一逻辑通过 
PORTALLOCATOR_ENABLE_SHARED_SOCKET flag 控制,前面我们就已经知道,默认情况下它是开启的。

 

/
收集 relay candidate 流程

第一次响应
SocketDispatcher::OnEvent(uint32_t ff, int err) ===> SignalReadEvent(this);
===> AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) ===>  SignalReadPacket(this, buf_, static_cast<size_t>(len), remote_addr,
                                                             (timestamp > -1 ? timestamp : TimeMicros()));
===> AllocationSequence::OnReadPacket(rtc::AsyncPacketSocket* socket,
                                      const char* data,
                                      size_t size,
                                      const rtc::SocketAddress& remote_addr,
                                      const int64_t& packet_time_us) ===> port->HandleIncomingPacket(socket, data, size, remote_addr, / TurnPort::HandleIncomingPacket
                                                                                                                                                                         packet_time_us)  

===> TurnPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
                                    const char* data,
                                    size_t size,
                                    const rtc::SocketAddress& remote_addr,
                                    int64_t packet_time_us)   ===> equest_manager_.CheckResponse(data, size);
===> StunRequestManager::CheckResponse(const char* data, size_t size) ===> return CheckResponse(response.get());
===> StunRequestManager::CheckResponse(StunMessage* msg) ===> request->OnErrorResponse(msg); // 401 未授权 TurnAllocateRequest::OnErrorResponse
===> TurnAllocateRequest::OnErrorResponse(StunMessage* response) ===> OnAuthChallenge(response, error_code); //  TurnAllocateRequest::OnAuthChallenge
===> TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) ===> port_->SendRequest(new TurnAllocateRequest(port_), 0); 重新发送一个带有 realm nonce 参数的 TurnAllocateRequest

第二次响应,这里直接到达和第一次处理 TurnAllocateRequest 响应不同的地方
StunRequestManager::CheckResponse(StunMessage* msg)  ===> request->OnResponse(msg);
===> TurnAllocateRequest::OnResponse(StunMessage* response) ===> port_->OnAllocateSuccess(relayed_attr->GetAddress(),
                                                                                                               mapped_attr->GetAddress()); /// TurnPort::OnAllocateSuccess 
===> TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
                                 const rtc::SocketAddress& stun_address) ===>   AddAddress(address,          // Candidate address.
                                                                                                                                                         address,          // Base address.
                                                                                                                                                         related_address,  // Related address.
                                                                                                                                                         UDP_PROTOCOL_NAME,
                                                                                                                                                         ProtoToString(server_address_.proto),  // The first hop protocol.
                                                                                                                                                         "",  // TCP canddiate type, empty for turn candidates.
                                                                                                                                                         RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto),
                                                                                                                                                         server_priority_, ReconstructedServerUrl(false /* use_hostname */),
                                                                                                                                                         true); /// 注意注意注意,这里 is_final 传递的是 true / 

===>     Port::AddAddress(const rtc::SocketAddress& address,
                      const rtc::SocketAddress& base_address,
                      const rtc::SocketAddress& related_address,
                      const std::string& protocol,
                      const std::string& relay_protocol,
                      const std::string& tcptype,
                      const std::string& type,
                      uint32_t type_preference,
                      uint32_t relay_preference,
                      const std::string& url,
                      bool is_final) { // 这里 is_final 传递的是 true // ===> FinishAddingAddress(c, is_final); // 这里 is_final 传递的是 true /
                      
===> Port::FinishAddingAddress(const Candidate& c, bool is_final) ===> SignalCandidateReady(this, c);
===> BasicPortAllocatorSession::OnCandidateReady ===> SignalCandidatesReady(this, candidates);
===> P2PTransportChannel::OnCandidatesReady ===> SignalCandidateGathered(this, candidates[i]);
===> JsepTransportController::OnTransportCandidateGathered_n ===> SignalIceCandidatesGathered(transport_name, {candidate});
===> PeerConnection::OnTransportControllerCandidatesGathered ===> OnIceCandidate(std::move(candidate)); 
===> PeerConnection::OnIceCandidate ===> Observer()->OnIceCandidate(candidate.get());
===> Conductor::OnIceCandidate ===> SendMessage(writer.write(jmessage)); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值