[英]How to read async server side streaming using GRPC c++
I am trying to implement asynchronous server-side streaming using C++.我正在尝试使用 C++ 实现异步服务器端流。 but I am not able to find any good example for the same.
但我找不到任何好的例子。 I am having a hard time reading stream asynchronously.
我很难异步读取 stream 。
Server Code服务器代码
class ServerImpl final
{
public:
~ServerImpl()
{
server_->Shutdown();
cq_->Shutdown();
}
void Run()
{
std::string server_address("0.0.0.0:50051");
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
std::cout << "Server listening on " << server_address << std::endl;
HandleRpcs();
}
private:
class CallData
{
public:
CallData(MultiGreeter::AsyncService* service, ServerCompletionQueue* cq)
: service_(service)
, cq_(cq)
, responder_(&ctx_)
, status_(CREATE)
, times_(0)
{
Proceed();
}
void Proceed()
{
if (status_ == CREATE)
{
status_ = PROCESS;
service_->RequestsayHello(&ctx_, &request_, &responder_, cq_, cq_, this);
}
else if (status_ == PROCESS)
{
if (times_ == 0)
{
new CallData(service_, cq_);
}
if (times_++ >= 3)
{
status_ = FINISH;
responder_.Finish(Status::OK, this);
}
else
{
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name() + ", no " + request_.num_greetings());
responder_.Write(reply_, this);
}
}
else
{
GPR_ASSERT(status_ == FINISH);
delete this;
}
}
private:
MultiGreeter::AsyncService* service_;
ServerCompletionQueue* cq_;
ServerContext ctx_;
HelloRequest request_;
HelloReply reply_;
ServerAsyncWriter<HelloReply> responder_;
int times_;
enum CallStatus
{
CREATE,
PROCESS,
FINISH
};
CallStatus status_;
};
void HandleRpcs()
{
new CallData(&service_, cq_.get());
void* tag;
bool ok;
while (true)
{
GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
}
}
std::unique_ptr<ServerCompletionQueue> cq_;
MultiGreeter::AsyncService service_;
std::unique_ptr<Server> server_;
};
client code客户代码
class GreeterClient
{
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(MultiGreeter::NewStub(channel))
{}
void SayHello(const std::string& user, const std::string& num_greetings)
{
HelloRequest request;
request.set_name(user);
request.set_num_greetings(num_greetings);
ClientContext context;
CompletionQueue cq;
void* got_tag = (void*)1;
bool ok = false;
std::unique_ptr<ClientAsyncReader<HelloReply>> reader(stub_>PrepareAsyncSayHello(&context,request, &cq));
std::cout << "Got reply: " << reply.message() << std::endl;
reader->Read(&reply,got_tag);
Status status;
reader->Finish(&status, (void*)1);
GPR_ASSERT(cq.Next(&got_tag, &ok));
GPR_ASSERT(ok);
if (status.ok())
{
std::cout << "sayHello rpc succeeded." << std::endl;
}
else
{
std::cout << "sayHello rpc failed." << std::endl;
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
}
}
private:
std::unique_ptr<MultiGreeter::Stub> stub_;
};
My proto service我的原型服务
rpc SayHello (HelloRequest) returns (stream HelloReply) {}
when I am reading the stream Synchronous manner using ClientReader it is working fine.当我使用 ClientReader 阅读 stream 同步方式时,它工作正常。 but when i am using ClientAsyncReader I am getting this runtime error.
但是当我使用 ClientAsyncReader 时,我收到了这个运行时错误。
Assertion failed: (started_), function Finish, file /usr/local/include/grpcpp/impl/codegen/async_stream_impl.h, line 250.
23:25:40: The program has unexpectedly finished.
Thanks in advance.提前致谢。
I have found several unit tests about server side streaming using async API in grpc source tree.我在 grpc 源代码树中发现了几个关于使用异步 API 的服务器端流的单元测试。 I think the unit test below will help you solve this problem.
我认为下面的单元测试将帮助您解决这个问题。
// One ping, two pongs.
TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
ResetStub();
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
EchoResponse recv_response;
Status recv_status;
ClientContext cli_ctx;
ServerContext srv_ctx;
ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
cq_.get(), cq_.get(), tag(2));
Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
srv_stream.Write(send_response, tag(3));
cli_stream->Read(&recv_response, tag(4));
Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
srv_stream.Write(send_response, tag(5));
cli_stream->Read(&recv_response, tag(6));
Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
srv_stream.Finish(Status::OK, tag(7));
cli_stream->Read(&recv_response, tag(8));
Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get());
cli_stream->Finish(&recv_status, tag(9));
Verifier().Expect(9, true).Verify(cq_.get());
EXPECT_TRUE(recv_status.ok());
}
ref.参考。 https://github.com/grpc/grpc/blob/master/test/cpp/end2end/async_end2end_test.cc#L654-L695
https://github.com/grpc/grpc/blob/master/test/cpp/end2end/async_end2end_test.cc#L654-L695
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.