void CUdpBase::ReadPendingData() { while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); ProcessRecvMsg(datagram); } }
/* OS_Error SslSvrSession::GenHttpRespMsg(StrPtrLen* cmdParams, const char* content, StrPtrLen *contentType, HTTPStatusCode status) { HTTPResponse httpResponse; UInt32 contentLen = content==NULL?0:strlen(content); httpResponse.CreateResponseHeader(http11Version, status); httpResponse.AppendDateField(); if(cmdParams && cmdParams->Len > 0) { httpResponse.AppendResponseHeader(httpPragmaHeader, cmdParams); } if(contentLen > 0) { httpResponse.AppendResponseHeader(httpContentTypeHeader, contentType==NULL?&HTTPBase::sContentTypeText:contentType); httpResponse.AppendContentLengthHeader(contentLen); } StrPtrLen* responseHeader = httpResponse.GetCompleteResponseHeader(); PutResponse(responseHeader->Ptr, responseHeader->Len); if(contentLen > 0) { PutResponse(content, contentLen); } return OS_NoErr; } */ SInt64 SslSvrSession::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) return -1; ZQ_Error err = ZQ_NoErr; while (this->IsLiveSession()) { // HTTP Session state machine. There are several well defined points in an HTTP request // where this session may have to return from its run function and wait for a new event. // Because of this, we need to track our current state and return to it. if(events&Task::kReadEvent) { switch(fState) { case kReadingRequest: { if ((err = fInputStream.ReadRequest(m_pssl)) == ZQ_NoErr) { // If the RequestStream returns QTSS_NoErr, it means // that we've read all outstanding data off the socket, // and still don't have a full request. Wait for more data. //+rt use the socket that reads the data, may be different now. fInputSocketP->RequestEvent(EV_RE); events -= Task::kReadEvent; break; } if ((err != ZQ_RequestArrived) && (err != E2BIG)) { // Any other error implies that the client has gone away. At this point, // we can't have 2 sockets, so we don't need to do the "half closed" check // we do below Assert(err > 0); // Assert(!this->IsLiveSession()); events -= Task::kReadEvent; break; } if (err == ZQ_RequestArrived) fState = kProcessingRequest; // If we get an E2BIG, it means our buffer was overfilled. // In that case, we can just jump into the following state, and // the code their does a check for this error and returns an error. if (err == E2BIG) fState = kCleaningUp; } case kProcessingRequest: { char* pBuffer = fInputStream.GetRequestBuffer(); UInt32 nLen = fInputStream.GetRequsetLength(); ZQ_Error err = ZQ_NoErr; while(err == ZQ_NoErr && nLen > 0) { err = ProcessRecvMsg(pBuffer, nLen); } if(ZQ_NoErr == err) { fState = kReadingRequest; return 0; // Update timer. //fTimeoutTask.RefreshTimeout(); } else { fState = kCleaningUp; } } break; case kCleaningUp: { // If we've gotten here, we've flushed all the data. Cleanup, // and wait for our next request! this->CleanupRequest(); fState = kReadingRequest; } break; }; } else if(events&Task::kWriteEvent) { OSMutexLocker locker(&fMutexList); ListElement *elem = NULL; int theLengthSent = 0; if((elem = fMsgList.first) != NULL) { // err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&fMsgList); if(NULL != fMsgList.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kZmqEvent) { events -= Task::kZmqEvent; } else { return 0; } } // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. return 0; }
SInt64 MqttServer::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) return -1; ZQ_Error err = ZQ_NoErr; while (this->IsLiveSession()) { // HTTP Session state machine. There are several well defined points in an HTTP request // where this session may have to return from its run function and wait for a new event. // Because of this, we need to track our current state and return to it. if(events&Task::kReadEvent) { if ((err = fInputStream.ReadRequest()) == ZQ_NoErr) { //+rt use the socket that reads the data, may be different now. fInputSocketP->RequestEvent(EV_RE); events -= Task::kReadEvent; continue; } if ((err != ZQ_RequestArrived) && (err != E2BIG)) { // Any other error implies that the client has gone away. At this point, // we can't have 2 sockets, so we don't need to do the "half closed" check // we do below Assert(err > 0); Assert(!this->IsLiveSession()); events -= Task::kReadEvent; break; } if (err == ZQ_RequestArrived) { char* pBuffer = fInputStream.GetRequestBuffer(); int nLen = fInputStream.GetRequsetLength(); ZQ_Error err = ZQ_NoErr; while(err == ZQ_NoErr && nLen > 0) { err = ProcessRecvMsg(pBuffer, nLen); } if(ZQ_NoErr == err) { err = fOutputStream.Flush(); if (err == EAGAIN) { UInt32 datalen = 0; char* pData = fOutputStream.GetBufferCopy(&datalen); if(pData) { OSMutexLocker locker(&fMutexList); ListAppend(&fMsgList, pData, datalen); } // If we get this error, we are currently flow-controlled and should // wait for the socket to become writeable again fSocket.RequestEvent(EV_RE | EV_WR); } } else { CleanupRequest(); } }; } else if(events&Task::kWriteEvent) { OSMutexLocker locker(&fMutexList); ListElement *elem = NULL; int theLengthSent = 0; if((elem = fMsgList.first) != NULL) { // err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&fMsgList); if(NULL != fMsgList.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kZmqEvent) { events -= Task::kZmqEvent; } else { return 0; } } // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. return 0; }