如何使用一种简单的方法来确定异步GRPC ++中客户端流的结束?

时间:2020-06-21 07:31:38

标签: c grpc

现在,我正在学习异步GRPC ++中的双向流。 感谢您的指导:https://github.com/Mityuha/grpc_async。我获得了很多有用的信息来了解此模式的实现原理,但对此有一个疑问: 无需多说,代码如下: 服务器:

if(!ok || mcounter >= greeting.size())//ctx_.IsCancelled() doesn't work
    {
        std::cout << "[ProceedMM]: Trying finish" << std::endl;
        status_ = FINISH;
        responder_.Finish(Status(), (void*)this);
    }

客户:

void AsyncCompleteRpc()
    {
        void* got_tag;
        bool ok = false;
        while(cq_.Next(&got_tag, &ok))
        {
            AbstractAsyncClientCall* call = static_cast<AbstractAsyncClientCall*>(got_tag);
            call->Proceed(ok);
        }
        std::cout << "Completion queue is shutting down." << std::endl;
    }

在此服务器中,ClientStream的末尾是由客户端发送的OK的布尔值来判断的。它与同步GRPC的方式不同,后者是通过返回{{1 }}多次出现在ServerReaderWriter的类中。在ServerAsyncReaderWriter的类中找到相同的方法bool Read(RequestType* request)很奇怪。尽管我知道这是由于异步的方法。但是,如果我不知道如何异步流很多次,没有“ OK”的判断,如何找到类似同步流的方式来判断客户端流的结束。因为我用java来测试性能,这是异步和异步方式之间相同的代码, t以异步方式具有确定的bool值。 有人可以帮我吗?或者告诉我一些解决方法,或者找到一种方法来测试Bazel在另一个问题中对GRPC ++的性能测试。

2 个答案:

答案 0 :(得分:0)

我不确定是否100%知道了问题,但是ok告诉您的是(错误时)您请求的操作无法完成,并且该端没有其他操作可以成功完成流。因此,如果您发出Read操作并且Next为您提供一个!ok值,那么您可以确保不再有任何数据从客户端返回。 CompletionQueue类的注释中提供了更详细的说明。

感谢gRPC并祝您好运。

答案 1 :(得分:0)

如果在gRPC的异步客户端中接收流,则将使用ClientAsyncReader<>类来接收数据。当发送和接收都是流时,此类有所不同,但是逻辑是相同的。

此类具有Finish()方法,在您将rpc数据发送到服务器后,需要调用该方法。来自服务器的应答流结束后,将向CompletionQueue添加一条消息,该消息对应于此方法。当其消息以CQ返回时,此Finish方法将返回最终状态。您可以发现流已完成。您的代码将与此类似:

response_reader_ = stub->PrepareAsyncXYZ(ctx_, req, cq);
response_reader_->StartCall(&start_data_);
response_reader_->Finish(&status_, &finish_data_);

在此示例中,CQ中的消息将带有finish_data_标签,您可以使用它来正确处理它。您可能将需要通过引用计数来管理Finish()Read()的消息,因为您可能还会收到其他失败的读取消息。在CQ中收到带有finish_data_的消息时,status_将具有有效的status值。

至少是我写的。