`

[Libjingle代码分析]随记

阅读更多

call_main.cc的main()方法中创建CallClient对象:
CallClient *client = new CallClient(pump.client());


CallClient is the top level manager for all calls in a voice chat application.



当登陆到Server后, XmppClient的SignalStateChange会传到CallClient::OnStateChange(), 这里会调用函数:
InitPhone();

在InitPhone()中一些很重要的对象被创建, 这些对象会在程序运行过程中一直被使用:
// 创建并运行Worker线程
worker_thread_ = new talk_base::Thread();
worker_thread_->Start();

// 创建NetworkManager对象
network_manager_ = new talk_base::NetworkManager();

// 创建PortAllocator对象
talk_base::SocketAddress stun_addr("stun.l.google.com", 19302);
  port_allocator_ =
      new cricket::BasicPortAllocator(network_manager_, stun_addr,
          talk_base::SocketAddress(), talk_base::SocketAddress(),
          talk_base::SocketAddress());
         
// 创建SessionManager对象
session_manager_ = new cricket::SessionManager(
      port_allocator_, worker_thread_);
     
     
// 创建并运行SessionManagerTask任务
session_manager_task_ =
      new cricket::SessionManagerTask(xmpp_client_, session_manager_);
  session_manager_task_->EnableOutgoingMessages();
  session_manager_task_->Start();   

// 创建MediaEngine对象
media_engine_ = cricket::MediaEngine::Create();        

// 创建MediaSessionClient对象
media_client_ = new cricket::MediaSessionClient(
      xmpp_client_->jid(),
      session_manager_,
      media_engine_,
      new cricket::DeviceManager());    
     
     
 当要place voice call的时候, CallClient::MakeCallTo()->CallClient::PlaceCall()被调用, 在CallClient::PlaceCall()里, Call对象和Session对象会被创建:
 call_ = media_client_->CreateCall();
 session_ = call_->InitiateSession(jid, options);
 
 
 MediaSessionClient is the top level manager for Call objects, each of which represents one or more voice chat connections. It also is the top level manager for handles creating the offer description by collecting the list of codecs supported by the computer. In addition to the base SessionClient tasks, it handles voice chat specific tasks such as reading and generating codec lists, choosing a codec, and managing global audio settings. It creates Call objects and the ChannelManager object. The application instantiates this object.

Call handles one or more Session objects, each representing a connection between two users. A multi-person chat would consist of a single Call object managing several Session objects, one per connection. The Call object handles the top-level jobs for that call, for example ending sessions, making a call to another user, accepting an incoming call, handling audio tasks such as mute and monitoring, and so on. It sends signals when sessions are created, ended, or change state (connecting, running, and so on). For outgoing calls, the application instantiates this object; for incoming calls, it is instantiated for you by MediaSessionClient.


在Call::InitiateSession()里,
Session *session = session_client_->CreateSession(this);
AddSession(session, offer);
session->Initiate(jid.Str(), offer);
 
在Call::AddSession()里,
voice_channel = session_client_->channel_manager()->CreateVoiceChannel(
      session, audio_offer->name, video_);

video_channel = session_client_->channel_manager()->CreateVideoChannel(
        session, video_offer->name, true, voice_channel);


在ChannelManager::CreateVoiceChannel()里, 调用CreateVoiceChannel_w(),然后创建VoiceChannel对象:
VoiceChannel* voice_channel = new VoiceChannel(
      worker_thread_, media_engine_.get(), media_channel,
      session, content_name, rtcp);

而VoiceChannel对象创建时会创建TransportChannel对象:
VoiceChannel::VoiceChannel(talk_base::Thread* thread,
                           MediaEngine* media_engine,
                           VoiceMediaChannel* media_channel,
                           BaseSession* session,
                           const std::string& content_name,
                           bool rtcp)
    : BaseChannel(thread, media_engine, media_channel, session, content_name,
                  session->CreateChannel(content_name, "rtp")),
      received_media_(false) {
  ...
}
而Session::CreateChannel()会首先创建(如果已经创建则直接获得)Transport对象:
TransportProxy* transproxy = GetOrCreateTransportProxy(content_name);
return transproxy->CreateChannel(channel_name, content_type_);


在Session::GetOrCreateTransportProxy()中,
Transport* transport =
      new P2PTransport(signaling_thread_,
                       session_manager_->worker_thread(),
                       session_manager_->port_allocator());
                      
在TransportProxy::CreateChannel()中,
TransportChannelProxy* channel =
      new TransportChannelProxy(name, content_type);


在Session::Initiate()里, 会调用SendInitiateMessage()发送session initiate消息给远端. 然后改变状态为STATE_SENTINITIATE, 这个会触发SignalState, 传给Call::OnSessionState().
然后触发SignalSessionState, 传给CallClient::OnSessionState(), CallClient会显示"Calling...".
在Session::Initiate()里, 也会调用SpeculativelyConnectAllTransportChannels(). TransportProxy::SpeculativelyConnectChannels()->Transport::ConnectChannels()->Transport::ConnectChannels_w()
->P2PTransportChannel::Connect()->
// Kick off an allocator session
Allocate();
->SignalRequestSignaling->Transport::OnChannelRequestSignaling()->SignalRequestSignaling->Session::OnTransportRequestSignaling()->SignalRequestSignaling->SessionManager::OnRequestSignaling()->CallClient::OnRequestSignaling()()
->session_manager_->OnSignalingReady()
->Session::OnSignalingReady()->Transport::OnSignalingReady()->P2PTransportChannel::OnSignalingReady()
->AddAllocatorSession(allocator_->CreateSession(name(), content_type()));
->PortAllocatorSession::GetInitialPorts()->BasicPortAllocatorSession::GetInitialPorts()->BasicPortAllocatorSession::OnAllocate()->AllocationSequence::OnMessage()->CreateUDPPorts()/CreateStunPorts()/CreateTCPPorts()              

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics