ARTSPConnection::postReceiveReponseEvent启动发送请求循环

    xiaoxiao2021-03-25  161

      下面贴出安卓N版本ARTSPConnection是如何启动向服务端发送请求,接收服务端的响应这样一个循环的:   

    ==> void ARTSPConnection::postReceiveReponseEvent() { //mReceiveResponseEventPending条件变量一旦postReceiveReponseEvent被调用就设置为true,知道整个循环调用达到末端该mReceiveResponseEventPending才会被设置为false,这样保证一次只存在一个这样的循环处理 if (mReceiveResponseEventPending) { return; } //新建一个消息msg,消息名为kWhatReceiveResponse,消息的处理者为this,也即ARTSPConnection //则该消息的处理发生在ARTSPConnection::onMessageReceived的case kWhatReceiveResponse处理分支 sp<AMessage> msg = new AMessage(kWhatReceiveResponse, this); msg->post(); //将mReceiveResponseEventPending变量设置为true,表示当前这样的一个循环正在进行中,不能再产生一次这样的循环。 mReceiveResponseEventPending = true; } ==> void ARTSPConnection::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatConnect: onConnect(msg); break; case kWhatDisconnect: onDisconnect(msg); break; case kWhatCompleteConnection: onCompleteConnection(msg); break; case kWhatSendRequest: onSendRequest(msg); break; case kWhatReceiveResponse: //调用onReceiveResponse()函数对消息名为kWhatReceiveResponse的消息进行处理 onReceiveResponse(); break; case kWhatObserveBinaryData: { CHECK(msg->findMessage("reply", &mObserveBinaryMessage)); break; } default: TRESPASS(); break; } } ==> void ARTSPConnection::onReceiveResponse() { //这样的一次循环调用接近到了末端,mReceiveResponseEventPending设置为false,表示可以再进行一次这样的循环调用了 mReceiveResponseEventPending = false; if (mState != CONNECTED) { return; } //创建一个timeval类型的时间结构体变量 struct timeval tv; tv.tv_sec = 0; tv.tv_usec = kSelectTimeoutUs; //创建一个套接字描述符集合rs //并将该套接字描述符集合内存清零 fd_set rs; FD_ZERO(&rs); //将之前创建的套接字描述符mSocket添加到该套接字描述符集合中 FD_SET(mSocket, &rs); //调用select函数检查套接字描述符集合rs里添加的套接字的状态, //即查询它的可读性、可写性及错误状态信息 //在这里查询可读性传入了 &rs,其他两个查询可写性及错误状态信息都是传入的NULL //说明在这里调用者只检查套接字描述符集合rs里套接字的可读性 int res = select(mSocket + 1, &rs, NULL, NULL, &tv); if (res == 1) { //刚才只通过FD_SET(mSocket, &rs)向套接字描述符集合rs里添加了一个我们创建的套接字描述符mSocket //所以select函数的返回值res为1说明,套接字描述符mSocket描述的套接口具有可读性 //调用MakeSocketBlocking(mSocket, true)函数阻塞该套接口,因为接下来需要从该套接口获取从服务端回应的消息 MakeSocketBlocking(mSocket, true); //真正的从套接口获取服务端回应的消息是在receiveRTSPReponse函数里完成 //后续文章为大家介绍receiveRTSPReponse函数 bool success = receiveRTSPReponse(); //成功从该套接口获取到服务端回应的消息后调用MakeSocketBlocking(mSocket, false)函数将该套接口设置为非阻塞状态 MakeSocketBlocking(mSocket, false); if (!success) { // Something horrible, irreparable has happened. flushPendingRequests(); return; } } //调用postReceiveReponseEvent()函数再次开启这样一次处理, //如此就形成了一个循环 postReceiveReponseEvent(); }

      小结:该循环的建立流程是:postReceiveReponseEvent ==> onReceiveResponse ==> postReceiveReponseEvent。这是一个设计技巧,是循环处理某些事务的机制,机制的原理就是形成一个循环调用圈。   select函数的百科介绍:select(),确定一个或多个套接口的状态,本函数用于确定一个或多个套接口的状态,对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息,用fd_set结构来表示一组等待检查的套接口,在调用返回时,这个结构存有满足一定条件的套接口组的子集,并且select()返回满足条件的套接口的数目。   

    转载请注明原文地址: https://ju.6miu.com/read-2868.html

    最新回复(0)