gprc 服务器在处理第二个请求时崩溃
Posted
技术标签:
【中文标题】gprc 服务器在处理第二个请求时崩溃【英文标题】:gprc server was crashed on processed second request 【发布时间】:2017-03-14 15:15:37 【问题描述】:最近我想在我的网络后端学习使用 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 调用时崩溃了 并且无法从调用堆栈中找到任何有用的信息
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 创建一个新对象作为其数据的容器。 ServerContext
和 Writer
不能在 RPC 之间共享。
【讨论】:
有没有办法重用请求上下文? 没有。您需要一些数据结构来表示 rpc,同时对两个 rpc 使用相同的数据结构没有任何意义。以上是关于gprc 服务器在处理第二个请求时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
从不同的 VC 访问时,带有完成处理程序的 API 调用函数崩溃