2017-03-14 9 views
0

に墜落した。最近、私は私のウェブバックエンドで使用grpcを勉強したいが、私の進捗gprcサーバが処理された第2の要求

サーバー壊れていくつかの問題が

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_; 
}; 

最終的にサーバを起動

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++ 

のコード例と異なるの私のコードは、そのサンプルコードは、後に新しい要求コンテキストを作成することです1つの要求を処理して、次の要求のために要求オブジェクトを再利用したい。

example code

答えて

1

あなたはそのデータのコンテナとして各RPCのための新しいオブジェクトを作成する必要があります。 ServerContextWriterはrpcsで共有できません。

+0

とにかくリクエストのコンテキストを再利用できますか? – tfzxyinhao

+0

いいえ。rpcを表現するためには何らかのデータ構造が必要です。同時に2つのrpcsに同じデータ構造を使用する意味がありません。 – Yang

関連する問題