gRPC (Cpp) Streaming - 如果在 grpc_impl::ServerReaderWriter::Read 期间一侧挂起或忘记关闭流,会发生啥?
Posted
技术标签:
【中文标题】gRPC (Cpp) Streaming - 如果在 grpc_impl::ServerReaderWriter::Read 期间一侧挂起或忘记关闭流,会发生啥?【英文标题】:gRPC (Cpp) Streaming - What happens if one side hangs or forgets to close the stream during grpc_impl::ServerReaderWriter::Read?gRPC (Cpp) Streaming - 如果在 grpc_impl::ServerReaderWriter::Read 期间一侧挂起或忘记关闭流,会发生什么? 【发布时间】:2020-10-21 13:58:12 【问题描述】:我正在尝试学习 gRPC cpp 示例。我在调试流式传输示例时注意到,服务器上对 grpc_impl::ServerReaderWriter::Read 的调用会阻塞,直到另一端写入或流结束。
我们应该如何使服务器足够健壮,以使其能够处理在发送初始消息后挂起或忘记关闭流的客户端?
也许它会进行 RPC 调用并向我发送三条消息,但从未关闭。 这个调用似乎没有超时的版本。
在这种情况下,我与所有客户端的整个通信线程不是被阻塞了吗?
【问题讨论】:
【参考方案1】:ServerReaderWriter::Read()
是 C++ 同步 API 的一部分,因此所有调用均按设计阻止。如果您想要异步行为,您可以切换到 C++ 异步 API,尽管使用起来要困难得多。
不过,如果您只关心客户端忘记关闭流的情况,您或许可以在不使用异步 API 的情况下解决该特定情况。在开始读取之前,您可以在另一个线程中设置一个计时器,如果在某个超时内读取未成功,它将调用ServerContext::TryCancel()
来取消流。这应该会导致读取返回并关闭流。
顺便说一句,请注意,在同步 API 中,每个请求处理程序都在其自己的线程中运行,因此在读取中阻塞一个流的请求处理程序不会影响服务器正在处理的任何其他流。因此,如果这就是您所担心的全部,您可能根本不需要做任何事情——阻塞读取就可以了。
【讨论】:
以上是关于gRPC (Cpp) Streaming - 如果在 grpc_impl::ServerReaderWriter::Read 期间一侧挂起或忘记关闭流,会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章