WEBRTC 如何建立P2P连接
媒体通道建立和信令通道建立
一.搜集候选地址
调用顺序
PeerConnection::SetLocalDescription->WebRtcSession::SetLocalDescription->
WebRtcSession::CreateChannels[创建传输通道和媒体通道,以视频为例]->
ChannelManager::CreateVideoChannel-> BaseChannel::Init_w->BaseChannel::InitNetwork_n->
BaseChannel::SetTransport_n-> TransportController::CreateTransportChannel_n->
TransportController::GetOrCreateTransport_n()->TransportController::CreateTransport_n()->
Transport::CreateChannel[创建P2PTransportChannel]->BaseChannel::SetTransportChannel_n->
BaseChannel::ConnectToTransportChannel[绑定P2P通道读写数据信号]->
WebRtcSession::MaybeStartGathering()[启动收集]->
TransportController::MaybeStartGathering_n()->Transport::MaybeStartGathering()->
P2PTransportChannel::MaybeStartGathering()->P2PTransportChannel::AddAllocatorSession[创建BasicPortAllocatorSession]->BasicPortAllocatorSession::StartGettingPorts-> BasicPortAllocatorSession::DoAllocate()[创建AllocationSequence]->AllocationSequence::CreateUDPPorts()[UDPPort::Create]|AllocationSequence::CreateStunPorts()[StunPort::Create]|AllocationSequence::CreateRelayPorts()[TurnPort::Create]|AllocationSequence::CreateTCPPorts()[TCPPort::Create]->BasicPortAllocatorSession::AddAllocatedPort()->
PortInterface:: PrepareAddress()[搜集候选地址UDPPort::PrepareAddress| TCPPort::PrepareAddress| TurnPort::PrepareAddress]->
TransportController::SetLocalTransportDescription->Transport::SetLocalTransportDescription->
Transport::ConnectChannels-> Transport::CallChannels->P2PTransportChannel::Connect()->
P2PTransportChannel::OnCheckAndPing()[向对方发起PING,但此时还未接收对方候选地址,还未调用P2PTransportChannel::AddConnection,故PING定时触发执行]
a创建SOCKET并接收PEER数据
WEBRTC所有提供服务的都是以抽象接口形式提供.
以创建UDP为例
-
创建AsyncPacketSocket对象(实际是AsyncUDPSocket的抽象类), 并对外暴露SignalReadPacket信号,并绑定到
TurnPort::OnReadPacket、UDPPort:: OnReadPacket、TCPPort::OnReadPacket
AsyncPacketSocket* PacketSocketFactory:: CreateUdpSocket()
由具体类BasicPacketSocketFactory实现,并在PeerConnectionFactory::Initialize()实例化
-
创建SocketFactory对象
由SocketServer::CreateDefault()在创建网络线程(network_thread_)时初始化,具体类为PhysicalSocketServer
-
创建AsyncSocket对象(实际SOCKET PhysicalSocket的抽象类),并对外暴露SignalReadEvent信号
由AsyncSocket* SocketFactory:: CreateAsyncSocket(int family, int type)->
PhysicalSocketServer::CreateAsyncSocket->SocketDispatcher::Create->
PhysicalSocket::Create(int family, int type)->
SocketDispatcher::Initialize()->PhysicalSocketServer::Add(Dispatcher*pdispatcher)
绑定SignalReadEvent信号
AsyncUDPSocket::AsyncUDPSocket(AsyncSocket*socket) : socket_(socket) {
socket_->SignalReadEvent.connect (this,&AsyncUDPSocket::OnReadEvent);
}
b建立连接对象
-
Connection对外暴露SignalReadPacket信号
-
P2PTransportChannel::OnReadPacket绑定SignalReadPacket信号(P2PTransportChannel::AddConnection)
-
TransportChannel (P2PTransportChannel抽象类),对外暴露SignalReadPacket信号
-
BaseChannel::ConnectToTransportChannel(TransportChannel* tc)
绑定TransportChannel 中的SignalReadPacket信号:
tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead);
二.发起连接对方
-
调用顺序
PeerConnection::AddIceCandidate-> WebRtcSession::ProcessIceMessage->WebRtcSession::UseCandidate-> TransportController::AddRemoteCandidates-> Transport::AddRemoteCandidates->P2PTransportChannel::AddRemoteCandidate->
P2PTransportChannel::CreateConnections-> P2PTransportChannel::CreateConnection->
PortInterface:: CreateConnection()[UDPPort::CreateConnection|TCPPort::CreateConnection| TurnPort::CreateConnection]->Port::AddConnection-> P2PTransportChannel::AddConnection[绑定连接对象的数据接收信号]->P2PTransportChannel::OnCheckAndPing()[定时由MSG_CHECK_AND_PING触发]
Connection::Ping[对方PEER响应Connection::ReceivedPingResponse()完成P2P连接成功
{ set_receiving(true); set_write_state(STATE_WRITABLE);set_state(STATE_SUCCEEDED); }]