前文我们梳理peerconnection_client的基本框架,本文我们从通话流程上梳理webrtc的P2P 通话的流程。首先上一张图经典的webrtc的P2P通话流程.
webrtc的P2P通话流程
基本流程:
bool MainWnd::OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT* result) {
switch (msg) {
case WM_ERASEBKGND:
*result = TRUE;
return true;
case WM_PAINT:
OnPaint(); //视频流的帧渲染及图形界面渲染
return true;
case WM_SETFOCUS: //编辑框聚焦定位
if (ui_ == CONNECT_TO_SERVER) {
SetFocus(edit1_);
} else if (ui_ == LIST_PEERS) {
SetFocus(listbox_);
}
return true;
case WM_SIZE://用来放大和缩小窗口
if (ui_ == CONNECT_TO_SERVER) {
LayoutConnectUI(true);
} else if (ui_ == LIST_PEERS) {
LayoutPeerListUI(true);
}
break;
case WM_CTLCOLORSTATIC:
*result = reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_WINDOW));
return true;
case WM_COMMAND://按键点击消息处理
if (button_ == reinterpret_cast<HWND>(lp)) {
if (BN_CLICKED == HIWORD(wp))
OnDefaultAction();
} else if (listbox_ == reinterpret_cast<HWND>(lp)) {
if (LBN_DBLCLK == HIWORD(wp)) {
OnDefaultAction();
}
}
return true;
case WM_CLOSE:
if (callback_)
callback_->Close();
break;
}
return false;
}
输入IP和端口,点击connect处理流程
---->触发一个window的WM_COMMAND事件,并调用OnDefaultAction
---> 调用callback_->StartLogin(server, port);
---> client_->Connect(server, port, GetPeerName());
---> DoConnect();
----> CreateClientSocket 创建客户端本地socket
--->初始始化 信号槽 InitSocketSignals();(用来接收对方socket数据的事件回调)
---->ConnectControlSocket 向服务器发送connect连接,完成三次握手
---->一旦连接到服务器,client通过OnConnect就给服务器发送一个http协议,报告主机名。
GET /sign_in?主机名 HTTP/1.0
----->服务器返回一个http 响应消息,然后关闭连接
--->-服务器读取响应消息后,向服务器使用另外一个hanging_get_发送
GET /wait?peer_id=12 HTTP/1.0\r\n
3.SDP协商
主叫:
---- >Conductor::ConnectToPeer
---- InitializePeerConnection
-----webrtc::CreateBuiltinAudioEncoderFactory(),
---- >CreatePeerConnection(这里可以配是否加密,ICE sever地址)
---->AddTracks(增加音视频track)---->StartLocalRenderer
---->CreateOffer
-----> OnSuccess---->SetLocalDescription-
----> SendMessage---> UIThreadCallback--->SendToPeer
被叫:
---OnMessageFromPeer----->SetRemoteDescription--->CreateAnswer
----- >OnSuccess---->-SetLocalDescription-
----> SendMessage---> UIThreadCallback--->SendToPeer
主叫:
--->OnMessageFromPeer----->SetRemoteDescription
4) ICE协商
被叫:
在SDP协商中SetLocalDescript触发---->OnIceCandidate---->endMessage--->UIThreadCallback------>SendToPeer
---->OnMessageFromPeer----->AddIceCandidate
主叫和被叫一样
在SDP协商中SetLocalDescript触发---->OnIceCandidate----> SendMessage-----> UIThreadCallback------>SendToPeer
------>OnMessageFromPeer---->-AddIceCandidate
5)媒体流接收:
收到对方的流---->触发OnAddTrack---->启动StartRemoteRenderer---->触发OnFrame产生解码后的YUV数据进行渲染。音频数据,在底层默认自己解码和渲染。因为音频与UI界面没有关系,所以数据没有必要送到上层处理,在底层就可以自己处理完毕。