2017-03-14 11 views
0

최근에 내가 내 웹 백엔드에 사용 grpc을 연구하고자하는 처리 두 번째 요청에 추락하지만, 일부 문제는 가 GPRC 서버는

내 요청이

를 구현하는 서버가

class CGreeterAsyncServerImpl 
{ 
public: 
    CGreeterAsyncServerImpl() 
     :run_(true){ 
    } 
    ~CGreeterAsyncServerImpl(){ 
     cq_->Shutdown(); 
     server_->Shutdown(); 
    } 

    void stop() { run_ = false; } 

    void Run(const char* addr) { 
     bool ok = false; 
     void* tag = nullptr; 
     ServerBuilder builder; 
     builder.AddListeningPort(addr, grpc::InsecureServerCredentials()); 
     builder.RegisterService(&service_); 
     cq_ = builder.AddCompletionQueue(true); 
     server_ = builder.BuildAndStart(); 

     std::shared_ptr<CMyAsyncRequest> ReqPtr(new CMyAsyncRequest(&service_, cq_.get())); 
     while (run_) 
     { 
      if (!cq_->Next(&tag, &ok)) break; 

      if (ok) { 
       ReqPtr->Process(); 
      } 
     } 
     std::cout << "run exit." << std::endl; 
    } 
private: 
    bool run_; 
    Greeter::AsyncService service_; 
    std::unique_ptr<Server> server_; 
    std::unique_ptr<ServerCompletionQueue> cq_; 
}; 
을 구현 나의

을 진행 부서졌다

class CMyAsyncRequest { public: CMyAsyncRequest(Greeter::AsyncService* service,ServerCompletionQueue* cq) :service_(service), resp_(&ctx_), cq_(cq), state_(RequestState::RS_PROCESS){ service_->RequestSayHello(&ctx_, &req_, &resp_, cq_, cq_, (void*)this); } void Process() { switch (state_) { case CMyAsyncRequest::RS_PROCESS: { std::string str("hello "); str.append(req_.name()); reply_.set_message(str); resp_.Finish(reply_, Status::OK,(void*)this); state_ = RequestState::RS_COMPLETED; } break; case CMyAsyncRequest::RS_COMPLETED: { req_.Clear(); service_->RequestSayHello(&ctx_, &req_, &resp_, cq_, cq_, (void*)this); state_ = RequestState::RS_PROCESS; } break; } } enum RequestState { RS_PROCESS, RS_COMPLETED }; RequestState state_; HelloRequest req_; HelloReply reply_; ServerContext ctx_; ServerCompletionQueue *cq_; Greeter::AsyncService* service_; ServerAsyncResponseWriter<HelloReply> resp_; }; 

마침내 서버 시작

,451,515,
CGreeterAsyncServerImpl server; 
server.Run("0.0.0.0:80"); 

내 서버는 두 번째 RPC 호출 을 처리 할 때 추락하고 호출 스택에서 어떤 유용한 정보를 찾을 수

grpc_server_sample.exe!issue_debug_notification(const wchar_t * const message) Line 125 C++ 
    grpc_server_sample.exe!__acrt_report_runtime_error(const wchar_t * message) Line 142 C++ 
    grpc_server_sample.exe!abort() Line 51 C++ 
    grpc_server_sample.exe!grpc::ServerContext::BeginCompletionOp(grpc::Call * call) Line 161 C++ 
    grpc_server_sample.exe!grpc::ServerInterface::BaseAsyncRequest::FinalizeResult(void * * tag, bool * status) Line 629 C++ 
    grpc_server_sample.exe!grpc::ServerInterface::PayloadAsyncRequest<sample::HelloRequest>::FinalizeResult(void * * tag, bool * status) Line 202 C++ 
    grpc_server_sample.exe!grpc::CompletionQueue::AsyncNextInternal(void * * tag, bool * ok, gpr_timespec deadline) Line 76 C++ 
    grpc_server_sample.exe!grpc::CompletionQueue::Next(void * * tag, bool * ok) Line 152 C++ 
    grpc_server_sample.exe!CGreeterAsyncServerImpl::Run(const char * addr) Line 218 C++ 
    grpc_server_sample.exe!main(int argc, char * * argv) Line 244 C++ 

예제 코드와 다른 내 코드는 예제 코드 후 새로운 요청 컨텍스트를 만드는 것입니다 하나의 요청을 처리 완료, 다음 요청에 대한 요청 개체를 재사용하고 싶습니다.

example code

답변

1

당신은 데이터의 컨테이너로 각 RPC에 대한 새로운 객체를 생성해야합니다. ServerContextWriter은 rpcs간에 공유 할 수 없습니다.

+0

어쨌든 요청 컨텍스트를 재사용 할 수 있습니까? – tfzxyinhao

+0

아니요. rpc를 나타 내기 위해 일부 데이터 구조가 필요하며 동시에 두 개의 RP에 대해 동일한 데이터 구조를 사용하는 것은 의미가 없습니다. – Yang