Debugging WebRTC Peer Connection with HTTP Data Exchange: A Comprehensive Packet Analysis

Continuing from the previous article, the first task after compiling WebRTC was to debug and analyze the peerconnection_client. I set up the peerconnection_server on a public server, while the peerconnection_client was run on two PCs—one laptop and one desktop. I analyzed the process using packet capture to monitor HTTP data exchange. [Click here to download the packet capture file](https://files.cnblogs.com/files/shawn-meng/peerconnection.pcapng.7z?t=1647592120).

sign_in

The peerconnection_client uses a socket to send HTTP data to send the sign_in command to the peerconnection_serverHTTP data exchange

The peerconnection_server responds with 200 OK, indicating that the peerconnection_client has registered. The corresponding code After the peerconnection_client clicks the connect button, through a series of redirects, calls the function void Conductor::StartLogin() –> void PeerConnectionClient::Connect() –> void PeerConnectionClient::DoConnect()

//peer_connection_client.cc//I modified the coding stylevoid PeerConnectionClient::DoConnect() {    control_socket_.reset(CreateClientSocket(server_address_.ipaddr().family()));    //Create a socket    hanging_get_.reset(CreateClientSocket(server_address_.ipaddr().family()));       //Create a socket    InitSocketSignals();    char buffer[1024];    //Set the data for the sing_in command, send HTTP data within the 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();    }}//Settings for the socket's operational events, OnClose, OnConnect, OnReadvoid 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 sending a wait command, the peerconnection_server keeps hanging until it receives a new client connection, it only then responds, including the complete client list in the response. As shown below, the server takes 218 seconds until another client connects before responding. After a signaling exchange completes, the socket closes (short HTTP connection).HTTP data exchange

The hanging socket hanging_get_ initiates a connection in void PeerConnectionClient::OnRead(rtc::AsyncSocket* socket). In the connection callback function void PeerConnectionClient::OnHangingGetConnect(), the wait command is sent

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. The callback to void Conductor::OnPeerConnected(int id, const std::string& name) displays the peer list in the window.

Connect to Peer

By double-clicking the peer’s name in the window, the connection request is triggered, and the offer is sent

Double-clicking the peer’s name initiates the function 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);    }}