首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gprc服务器在处理后的第二个请求中崩溃。

gprc服务器在处理后的第二个请求中崩溃。
EN

Stack Overflow用户
提问于 2017-03-14 15:15:37
回答 1查看 639关注 0票数 0

最近我想在我的web后端上学习使用grpc,但是有一些问题破坏了我的进步。

服务器实现

代码语言:javascript
复制
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_;
};

我的请求实现了

代码语言:javascript
复制
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_;
};

最后启动服务器

代码语言:javascript
复制
CGreeterAsyncServerImpl server;
server.Run("0.0.0.0:80");

我的服务器在处理第二个rpc调用时崩溃,无法从调用堆栈中找到任何有用的信息。

代码语言:javascript
复制
    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++

我的代码与示例代码不同的是,示例代码在完成一个请求后创建新的请求上下文,我希望为下一个请求重用request对象。

示例代码

EN

回答 1

Stack Overflow用户

发布于 2017-04-05 04:44:59

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42789806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档