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つの要求を処理して、次の要求のために要求オブジェクトを再利用したい。
とにかくリクエストのコンテキストを再利用できますか? – tfzxyinhao
いいえ。rpcを表現するためには何らかのデータ構造が必要です。同時に2つのrpcsに同じデータ構造を使用する意味がありません。 – Yang