gprc服务器在处理完的第二个请求时崩溃了

时间:2017-03-14 15:15:37

标签: c++ backend rpc grpc

最近我想学习在我的网络后端使用grpc,但有些问题打破了我的进步

服务器工具

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调用时崩溃了 并且无法从callstack

中找到任何有用的信息
    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 个答案:

答案 0 :(得分:1)

您需要为每个rpc创建一个新对象作为其数据的容器。无法在rpcs之间共享ServerContextWriter