首页 > 解决方案 > 如何在 C++ 中向 grpc 完成队列添加事件?

问题描述

我正在尝试实现一个异步 GRPC 服务器,每当客户端进行调用时,它都会获得不确定的消息流。我通读了官方文档。它不包括我想为每个 RPC 保持流打开的场景。这篇文章 - https://www.gresearch.co.uk/article/lessons-learnt-from-writing-asynchronous-streaming-grpc-services-in-c/ 通过基本上放置回调来解决保持流打开的问题再次完成队列中的处理程序对象。

文章建议:

if (HasData())
{
    responder_.Write(reply_, this);
}
else
{
    grpc::Alarm alarm;
    alarm.Set(completion_queue_, gpr_now(gpr_clock_type::GPR_CLOCK_REALTIME), this);
}

我尝试按照本文中的建议使用 Alarm 对象方法,但由于某种原因,Next在完成队列的下一个函数调用中,我得到ok的参数为 false - GPR_ASSERT(cq_->Next(&tag, &ok));。结果,我必须关闭服务器并且无法等待流,直到有更多数据可用。

我能够很好地接收数据,直到else案件没有被击中。

有人可以帮我确定我可能做错了什么吗?我无法在 GRPC 上找到很多 C++ 资源。谢谢!

标签: c++grpc

解决方案


  1. 当 Alarm 超出范围时,它将生成一个 Cancel() 导致您在 Next() 中获得 !ok。

  2. 如果您想使用它,您需要将警报放入您的类范围并触发它:

    std::unique_ptr<Alarm> alarm_;
    alarm_.reset(new Alarm);
    alarm_->Set(cq_, grpc_timeout_seconds_to_deadline(10), this);

来自关于 Alarm::Set 的文档:

在指定时间触发完成队列 cq 上的警报实例。

一旦警报到期(在截止日期)或它被取消(见取消),一个带有标签的事件将被添加到 cq。如果警报过期,则事件的成功位将为真,否则为假(即在取消时)。


推荐阅读