Debugging and Analyzing the peerconnection_client in WebRTC: A Step-by-Step Guide

Following the previous article on compiling webrtc, the first thing to debug and analyze is the peerconnection_client. I set up the peerconnection_server on a public server, with the peerconnection_client running on two PCs—one laptop and one desktop—and used packet capturing to analyze the process. The packet capture file can be downloaded here.

sign_in

The peerconnection_client uses a socket to send HTTP data to issue a sign_in command to the peerconnection_server. webrtc debug />

The peerconnection_server responds with 200 OK, indicating that the peerconnection_client has been registered. The corresponding code is executed by clicking the connect button on the peerconnection_client, which, after some redirections, calls void Conductor::StartLogin() –> void PeerConnectionClient::Connect() –> void PeerConnectionClient::DoConnect()

//peer_connection_client.cc//I have modified the coding stylevoid PeerConnectionClient::DoConnect() {    control_socket_.reset(CreateClientSocket(server_address_.ipaddr().family()));    //create socket    hanging_get_.reset(CreateClientSocket(server_address_.ipaddr().family()));       //create socket    InitSocketSignals();    char buffer[1024];    //Configure sign_in command data, send HTTP data via raw socket    snprintf(buffer, sizeof(buffer), "GET /sign_in?%s HTTP/1.0\r\n\r\n", client_name_.c_str());    onconnect_data_ = buffer;    bool ret = ConnectControlSocket(); //socket connect server    if (ret) {        state_ = SIGNING_IN;    }    if (!ret) {        callback_->OnServerConnectionFailure();    }}//Here the socket's actionable events like OnClose, OnConnect, OnRead are setvoid PeerConnectionClient::InitSocketSignals() {    RTC_DCHECK(control_socket_.get() != NULL);    RTC_DCHECK(hanging_get_.get() != NULL);    control_socket_->SignalCloseEvent.connect(this, &PeerConnectionClient::OnClose);    hanging_get_->SignalCloseEvent.connect(this, &PeerConnectionClient::OnClose);    control_socket_->SignalConnectEvent.connect(this, &PeerConnectionClient::OnConnect);    hanging_get_->SignalConnectEvent.connect(this, &PeerConnectionClient::OnHangingGetConnect);    control_socket_->SignalReadEvent.connect(this, &PeerConnectionClient::OnRead);    hanging_get_->SignalReadEvent.connect(this, &PeerConnectionClient::OnHangingGetRead);}

After the socket successfully connects to the peerconnection_server, it triggers the OnConnect callback, where the sign_in command is sent.

void PeerConnectionClient::OnConnect(rtc::AsyncSocket* socket) {    RTC_DCHECK(!onconnect_data_.empty());    size_t sent = socket->Send(onconnect_data_.c_str(), onconnect_data_.length());    RTC_DCHECK(sent == onconnect_data_.length());    onconnect_data_.clear();}

In void PeerConnectionClient::OnRead(rtc::AsyncSocket* socket), the server’s response is received.

wait

After the peerconnection_client sends a wait command, the peerconnection_server remains suspended until a new client connection is received. Only then does it respond, including a list of all clients in the response. As shown below, after 218 seconds, a new client connection is made, prompting a server response. After completing one signal exchange, the socket closes (HTTP short connection). webrtc debug />

The hanging socket is initiated in void PeerConnectionClient::OnRead(rtc::AsyncSocket* socket) and the wait command is sent in the connection callback function void PeerConnectionClient::OnHangingGetConnect().

void PeerConnectionClient::OnHangingGetConnect(rtc::AsyncSocket* socket) {    char buffer[1024];    snprintf(buffer, sizeof(buffer), "GET /wait?peer_id=%i HTTP/1.0\r\n\r\n", my_id_);    int len = static_cast(strlen(buffer));    int sent = socket->Send(buffer, len);    RTC_DCHECK(sent == len);}

Then, in void PeerConnectionClient::OnHangingGetRead(rtc::AsyncSocket* socket), the server’s response is received. This callback leads to void Conductor::OnPeerConnected(int id, const std::string& name) to display the peer list in the window.

Connecting to peer

Double-clicking a peer’s name in the window initiates a connection and sends an offer.

Double-clicking a peer’s name calls void Conductor::ConnectToPeer()

void Conductor::ConnectToPeer(int peer_id) {    RTC_DCHECK(peer_id_ == -1);    RTC_DCHECK(peer_id != -1);    if (peer_connection_.get()) {        main_wnd_->MessageBox("Error", "We only support connecting to one peer at a time", true);        return;    }    //Initialize audio and video    if (InitializePeerConnection()) {        peer_id_ = peer_id;        //Generate offer SDP information        peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());    } else {        main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);    }}