std::string GCGV_ReqGetNodes::OnRequest(const char* JSON) { SetupRequest(JSON); FindNodes(); BuildReply(); return reply.GetAndClear(); }
/*! \brief 事件由ServiceSession Task进行处理,大多数为网络报文处理事件 \param \return 处理完成返回0,断开Session返回-1 \ingroup \see */ SInt64 CServiceSession::Run() { //获取事件类型 EventFlags events = this->GetEvents(); QTSS_Error err = QTSS_NoErr; QTSSModule* theModule = NULL; UInt32 numModules = 0; // Some callbacks look for this struct in the thread object OSThreadDataSetter theSetter(&fModuleState, NULL); //超时事件或者Kill事件,进入释放流程:清理 & 返回-1 if (events & Task::kKillEvent) fLiveSession = false; if(events & Task::kTimeoutEvent) { //客户端Session超时,暂时不处理 char msgStr[512]; qtss_snprintf(msgStr, sizeof(msgStr), "session timeout,release session\n"); QTSServerInterface::LogError(qtssMessageVerbosity, msgStr); return -1; } //正常事件处理流程 while (this->IsLiveSession()) { //报文处理以状态机的形式,可以方便多次处理同一个消息 switch (fState) { case kReadingFirstRequest://首次对Socket进行读取 { if ((err = fInputStream.ReadRequest()) == QTSS_NoErr) { //如果RequestStream返回QTSS_NoErr,就表示已经读取了目前所到达的网络数据 //但,还不能构成一个整体报文,还要继续等待读取... fInputSocketP->RequestEvent(EV_RE); return 0; } if ((err != QTSS_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()); break; } if ((err == QTSS_RequestArrived) || (err == E2BIG)) fState = kHaveCompleteMessage; } continue; case kReadingRequest://读取请求报文 { //读取锁,已经在处理一个报文包时,不进行新网络报文的读取和处理 OSMutexLocker readMutexLocker(&fReadMutex); //网络请求报文存储在fInputStream中 if ((err = fInputStream.ReadRequest()) == QTSS_NoErr) { //如果RequestStream返回QTSS_NoErr,就表示已经读取了目前所到达的网络数据 //但,还不能构成一个整体报文,还要继续等待读取... fInputSocketP->RequestEvent(EV_RE); return 0; } if ((err != QTSS_RequestArrived) && (err != E2BIG) && (err != QTSS_BadArgument)) { //Any other error implies that the input connection has gone away. // We should only kill the whole session if we aren't doing HTTP. // (If we are doing HTTP, the POST connection can go away) Assert(err > 0); if (fOutputSocketP->IsConnected()) { // If we've gotten here, this must be an HTTP session with // a dead input connection. If that's the case, we should // clean up immediately so as to not have an open socket // needlessly lingering around, taking up space. Assert(fOutputSocketP != fInputSocketP); Assert(!fInputSocketP->IsConnected()); fInputSocketP->Cleanup(); return 0; } else { Assert(!this->IsLiveSession()); break; } } fState = kHaveCompleteMessage; } case kHaveCompleteMessage://读取到完整的请求报文 { Assert( fInputStream.GetRequestBuffer() ); Assert(fRequest == NULL); //根据具体请求报文构造HTTPRequest请求类 fRequest = NEW HTTPRequest(&sServiceStr, fInputStream.GetRequestBuffer()); //在这里,我们已经读取了一个完整的Request,并准备进行请求的处理,直到响应报文发出 //在此过程中,此Session的Socket不进行任何网络数据的读/写; fReadMutex.Lock(); fSessionMutex.Lock(); //清空发送缓冲区 fOutputStream.ResetBytesWritten(); //网络请求超过了缓冲区,返回Bad Request if (err == E2BIG) { //返回HTTP报文,错误码408 //(void)QTSSModuleUtils::SendErrorResponse(fRequest, qtssClientBadRequest, qtssMsgRequestTooLong); fState = kSendingResponse; break; } // Check for a corrupt base64 error, return an error if (err == QTSS_BadArgument) { //返回HTTP报文,错误码408 //(void)QTSSModuleUtils::SendErrorResponse(fRequest, qtssClientBadRequest, qtssMsgBadBase64); fState = kSendingResponse; break; } Assert(err == QTSS_RequestArrived); fState = kFilteringRequest; } case kFilteringRequest: { //刷新Session保活时间 fTimeoutTask.RefreshTimeout(); //对请求报文进行解析 QTSS_Error theErr = SetupRequest(); //当SetupRequest步骤未读取到完整的网络报文,需要进行等待 if(theErr == QTSS_WouldBlock) { this->ForceSameThread(); fInputSocketP->RequestEvent(EV_RE); // We are holding mutexes, so we need to force // the same thread to be used for next Run() return 0;//返回0表示有事件才进行通知,返回>0表示规定事件后调用Run } //每一步都检测响应报文是否已完成,完成则直接进行回复响应 if (/*fRequest->HasResponseBeenSent()*/fOutputStream.GetBytesWritten() > 0) { fState = kSendingResponse; break; } fState = kPreprocessingRequest; break; } case kPreprocessingRequest: { //请求预处理过程 //TODO:报文处理过程 fState = kCleaningUp; break; } case kProcessingRequest: { if (fOutputStream.GetBytesWritten() == 0) { //如果到这里,响应报文还没有形成,返回500 Server Internal Error ////QTSSModuleUtils::SendErrorResponse(fRequest, qtssServerInternal, qtssMsgNoModuleForRequest); } fState = kSendingResponse; } case kSendingResponse: { //响应报文发送,确保完全发送 Assert(fRequest != NULL); //发送响应报文 err = fOutputStream.Flush(); if (err == EAGAIN) { // If we get this error, we are currently flow-controlled and should // wait for the socket to become writeable again //如果收到Socket EAGAIN错误,那么我们需要等Socket再次可写的时候再调用发送 fSocket.RequestEvent(EV_WR); this->ForceSameThread(); // We are holding mutexes, so we need to force // the same thread to be used for next Run() return 0; } else if (err != QTSS_NoErr) { // Any other error means that the client has disconnected, right? Assert(!this->IsLiveSession()); break; } fState = kCleaningUp; } case kCleaningUp: { // Cleaning up consists of making sure we've read all the incoming Request Body // data off of the socket if (this->GetRemainingReqBodyLen() > 0) { err = this->DumpRequestData(); if (err == EAGAIN) { fInputSocketP->RequestEvent(EV_RE); this->ForceSameThread(); // We are holding mutexes, so we need to force // the same thread to be used for next Run() return 0; } } //一次请求的读取、处理、响应过程完整,等待下一次网络报文! this->CleanupRequest(); fState = kReadingRequest; } } } //清空Session占用的所有资源 this->CleanupRequest(); //Session引用数为0,返回-1后,系统会将此Session删除 if (fObjectHolders == 0) return -1; //如果流程走到这里,Session实际已经无效了,应该被删除,但没有,因为还有其他地方引用了Session对象 return 0; }