C++音视频

代码改变世界

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

继上一篇,编译webrtc后,首先调试分析的就是peerconnection_client。
我把peerconnection_server放到一个公网服务器,peerconnection_client运行在两台pc上,一台笔记本,一台台式机,通过抓包来分析流程。抓包文件可以点击此处下载

sign_in

peerconnection_client使用socket发送http数据方式来发送sign_in命令给peerconnection_server

peerconnection_server应答200OK,表示peerconnection_client已注册上。
代码对应
peerconnection_client点击connect按钮后,经过跳转,会调用到 void Conductor::StartLogin() --> void PeerConnectionClient::Connect() --> void PeerConnectionClient::DoConnect()

//peer_connection_client.cc
//我修改过编码风格
void PeerConnectionClient::DoConnect() {
    control_socket_.reset(CreateClientSocket(server_address_.ipaddr().family()));    //创建socket
    hanging_get_.reset(CreateClientSocket(server_address_.ipaddr().family()));       //创建socket
    InitSocketSignals();
    char buffer[1024];
    //设置sing_in的命令数据,裸socket里发送http数据
    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();
    }
}
//在这里设置了socket的可操作事件,OnClose,OnConnect,OnRead
void 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);
}

然后socket连接peerconnection_server成功后,触发OnConnect回调,在此回调里发送sign_in命令

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();
}

在void PeerConnectionClient::OnRead(rtc::AsyncSocket* socket)接收到server的应答。

wait

peerconnection_client发送wait后,peerconnection_server会一直挂起,直到peerconnection_server接收到新的client连接,才会应答,然后在应答里带上所有的client列表。
如下图,server过了218秒有新的client连接,才应答。完成一次信令交互后,socket关闭(http短连接)。

挂起socket hanging_get_在void PeerConnectionClient::OnRead(rtc::AsyncSocket* socket)中发起连接,在连接回调函数 void PeerConnectionClient::OnHangingGetConnect()中发送命令 wait

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<int>(strlen(buffer));
    int sent = socket->Send(buffer, len);
    RTC_DCHECK(sent == len);
}

然后在 void PeerConnectionClient::OnHangingGetRead(rtc::AsyncSocket* socket)接收到server的应答。回调到void Conductor::OnPeerConnected(int id, const std::string& name)在窗口显示对端列表。

连接peer

在窗口上双击对端的名称,触发连接对端,发送offer

在窗口上双击对端的名称,调到 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;
    }
    //初始化音视频
    if (InitializePeerConnection()) {
        peer_id_ = peer_id;
        //产生offer sdp信息
        peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
    } else {
        main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);
    }
}
posted on 2022-03-18 11:55  shunxiang  阅读(420)  评论(0)    收藏  举报