WebRTC peerconnection_client/peerconnection_server分析

可从https://download.csdn.net/download/dotphoenix/10505139下载测试程序,如需修改过的源码可联系[email protected],或者直接从https://download.csdn.net/download/dotphoenix/10513835下载
整体说明 
bfWebRTC基于webrtc-native自带的peerconnection_client项目,实现了一个简单的信令协议客户端(服务器端位于bfWebRTCServer),并且使用webrtc音视频引擎来建立音视频通话。
bfWebRTC支持如下功能:
1.          信令客户端,用于呼叫建立机终止,代码主要位于peer_connection_client类中。
2.          支持音视频采集,播放,ICE框架,音频处理等,代码主要位于conductor类中。
测试步骤:
运行bfWebRtcServer.exe,该程序是一个信令服务器+中转服务器,信令服务器使用的是默认8888端口,中转服务器默认使用9999端口;该中转服务器仅仅支持一对通话,并且下次通话的时候需要重启该程序(因为中转服务器未实现清空上次通话数据的能力)。
 
bfWebRTC是客户端。通话的双方需要将他们各自的candidate里面的ip和端口都设为中转服务器的地址和端口(参考conductor类里面的OnIceCandidate函数的set_address调用)。
 
理论上讲fWebRtcServer.exe可以运行于公网上,只要在bfWebRTC里面设置正确的公网地址和端口即可。
 
文件说明
1.          Defaults.h和flagdefs.h中主要用于定义几个常量。
2.          Json_xxx系列文件及类主要用于json格式的构造和解析,因为信令格式是基于json的。
3.          Peer_connection_client主要用于信令的建立,sdp和candidate的交换,可以理解该类就是一个sip客户端,主要由该类调用conductor类中的函数,建立媒体流;推荐的做法是使用子节点sip类替换该类,不改动其架构。
4.          Conductor类,主要是封装了webrtc抽象出来的类,用于建立媒体流;该类是建立媒体连接的核心类,务必完全理解。
5.           Main_wnd类,界面的实现,注意其消息循环。
6.          Main.cc文件,该文件是启动类,注意,因为webrtc内部很多地方使用的是异步调用,依赖系统的主消息循环,所以必须参考该类的写法,最好不要使用基于mfc的框架,如果旧的界面库无法弃用,建议做成两个不同的进程,使用进程间通信来完成通信的建立。
详细说明
1.          Main.cc
在初始化的时候,必须调用全局的初始化函数。
 rtc::EnsureWinsockInit();
  rtc::Win32SocketServerw32_ss;
 rtc::Win32Threadw32_thread(&w32_ss);
 rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
rtc::InitializeSSL();
 
在退出时必须调用
rtc::CleanupSSL();
 
特别注意conductor类的构建,scoped_refptr类型的指针不能乱用;
 PeerConnectionClientclient;
  rtc::scoped_refptr<Conductor> conductor(
        newrtc::RefCountedObject<Conductor>(&client, &wnd));
 
2.          Peer_connection_client.h类
 
structPeerConnectionClientObserver{
 virtualvoidOnSignedIn() = 0; // 登录服务器成功
 virtualvoidOnDisconnected() = 0;//与服务器连接中断,通常是我们主动断开连接,比如退出登录等
 virtualvoidOnPeerConnected(intid, conststd::string& name) = 0; //有新的peer登录到服务器
 virtualvoidOnPeerDisconnected(intpeer_id) = 0; //有peer与服务器中断连接
 virtualvoidOnMessageFromPeer(intpeer_id, conststd::string& message) = 0; //有消息从peer发给我
 virtualvoidOnMessageSent(interr) = 0; //消息发送成功
 virtualvoidOnServerConnectionFailure() = 0; //与服务器的连接中断,通常是被动,比如登录服务器失败
 
 protected:
 virtual~PeerConnectionClientObserver() {}
};
该接口用于当信令层有变化的时候通知对该变化感兴趣的调用者。在该项目,conductor类实现了该接口,用于当信令层变化的时候,通知界面或者更新媒体部分。
 
注意:
和界面的交互是由conductor类完成的(通过调用UI层向其注册的MainWndCallback接口实现来完成),这和我们想象的通常应该由信令层和界面交互,然后调用媒体层不太一样,猜测可能的原因是conductor类需要系统的消息循环配合工作,比如有些由底层回调的函数不能操作某些函数(这些函数需要在主消息循环里面进行)。所有如果信令层有变化需要通知UI(比如登录成功,登录失败等需要刷新界面时),则通过调用conductor实现的接口类(PeerConnectionClientObserver)来实现。
 
 
int my_id_; 
//信令服务器分配给我们的id,存储于http头的如下字段:Pragma: 10,另外在服务器推送的数据中(比如有新登录的peer),content字段如下: alex1527474869@alex-imac-win7,10,1,第二个字段如果和这个一样,那就是我们自己,如果不一样,就是一个新的peer。
 
信令客户端会和服务器建立两个异步socket
std::unique_ptr<rtc::AsyncSocket> control_socket_; //用于发送数据给服务器,发送onconnect_data_里面的数据
std::unique_ptr<rtc::AsyncSocket> hanging_get_; //用于接收服务器主动推送过来的消息
std::string onconnect_data_; //发送给control_socket_的数据, 用于登录,退出,呼叫其它peer,给通话的peer新的candidate,和通话的peer断开等。
std::string control_data_; 收取从control_socket_读到的数据,通常发送成功,就接着读取response,这个其实可以设为局部变量,只有一个函数使用
std::string notification_data_; //hanging_get_这个socket推送过来的通知消息,一般是peer上线/下线,或者被呼叫的SDP,或者对方新的candidate等,OnMessageFromPeer主要处理
std::string client_name_;//我们自己的名字
Peers peers_; //当前系统所有已登录的peer,是一个id-name的映射
 
OnXXXX函数,该类使用了webrtc自带的sigslot机制,AsyncSocket基于该机制,可以向其注册回调函数,当不同的网络事件发生后,回调函数会被调用,比如OnConnect表示连接成功,OnRead表示有数据收到,OnClose表示连接中断。
 
 
3.          Conductor类
Conductor类封装了webrtc提供的完整媒体能力。并且负责和界面交互;他实现了四个接口:
webrtc::PeerConnectionObserver //PeerConnection回调接口,用于RTCPeerConnection事件,主要注意其OnIceCandidate函数,这个函数当底层有新的candidate产生的时候会被回调,注意这个函数对我们也非常重要,我们的机制是通过修改candidate里面的address来强制使用中转服务器,所以当我们收到该回调后,需要修改ip和port的值,然后再发送给peer.
webrtc::CreateSessionDescriptionObserver // 底层生成SDP后回调,我们将此SDP发送给peer,这个通常主叫才会生成,被叫通常需要将此SDP交与底层。
PeerConnectionClientObserver//用于当信令层有变化的时候通知
MainWndCallback//用于主界面的操作
 
  intpeer_id_; //呼叫建立的对方的peer id
  boolloopback_; //是否本地loopback,可以不管
  rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;//webrtc核心类,由工厂peer_connection_factory_创建,用于管理一次媒体通信相关的资源,比如端口分配,ice配置等。
  rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
      peer_connection_factory_; //webrtc核心工厂类,用于管理音视频的编解码工厂,音频设备工厂,工作线程等。
  std::unique_ptr<rtc::BasicNetworkManager> default_network_manager_; //如果需要自己指定rtp端口,需要实现该类
  std::unique_ptr<cricket::PortAllocator> port_allocator_;//rtp端口分配的实现类,如果需要自定义端口返回,参考代码的NOT_USE_DEFAULT_RTP_PORT宏定义
#ifdefNOT_USE_DEFAULT_RTP_PORT
  PeerConnectionClient* client_; //信令连接对象
  MainWindow* main_wnd_;//主窗口对象
  std::deque<std::string*> pending_messages_; //待发送消息
  std::stringserver_; //服务器地址
注意:
a.   SendMessageToUI和UIThreadCallback这2个函数要特别注意,相当于有些数据或者事件要处理的时候,不能直接处理,需要先使用SendMessageToUI将消息发送给主界面内,然后主界面类再调用UIThreadCallback函数来处理该消息,原因在前面已经讲过了,就是webrtc有些类和函数只能在有消息循环的线程里面调用。
 
b.          SUPPORT_VIDEO宏控制是否需要指出VIDEO
c.           SIP如果要调用该类,建议也实现类似的架构,当OnSuccess回调的时候,需要将SDP发送给对方;当OnIceCandidate回调的时候,修改相关的值之后,要通过相关SIP指令发送给对方。
 
4.          Main_wnd类,界面实现的主类,其定义了MainWndCallback接口,并且实现该接口的类要通过调用RegisterObserver函数将其注册给main_wnd类。
XXXRenderer相关函数跟视频有关,可以忽略
 

猜你喜欢

转载自blog.csdn.net/dotphoenix/article/details/80841249