最近我想学习在我的网络后端使用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++
我的代码与示例代码不同的是,示例代码在完成一个请求后创建新的请求上下文,我想重新使用请求对象进行下一个请求。
答案 0 :(得分:1)
您需要为每个rpc创建一个新对象作为其数据的容器。无法在rpcs之间共享ServerContext
和Writer
。