检测在 grpc 服务器中关闭的客户端连接

Posted

技术标签:

【中文标题】检测在 grpc 服务器中关闭的客户端连接【英文标题】:detect client connection closed in the grpc server 【发布时间】:2019-11-02 08:42:15 【问题描述】:

在grpc Github (client) 和(server) 中提供的unary RPC 示例中,有什么方法可以检测到客户端关闭的连接吗?

例如在server.cc文件中:

std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());

// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
status_ = FINISH;
int p = 0,i=0;
while(i++ < 1000000000)  // some dummy work
        p = p + 10;

responder_.Finish(reply_, Status::OK, this);

在将响应发送回客户端之前,使用此虚拟任务,服务器将需要几秒钟。如果我们关闭客户端(例如使用Ctrl+C),服务器不会抛出任何错误。它只是简单地调用Finish,然后像Finish 成功一样释放对象。

服务器端是否有任何async 功能(处理函数)来通知我们客户端已关闭连接或客户端已终止?

谢谢!

【问题讨论】:

【参考方案1】:

很遗憾,没有。

但是现在 gRPC 团队的人正在努力将回调机制实现到 C++ 实现中。据我了解,它的工作方式与 Java 实现相同(https://youtu.be/5tmPvSe7xXQ?t=1843)。

您可以通过以下示例了解如何使用未来的 API:client_callback.cc 和 server_callback.cc

您感兴趣的一点是来自服务器端::grpc::experimental 命名空间的ServerBidiReactor 类。它有OnDoneOnCancel 通知方法,也许可以帮助你。

另一个有趣的地方是,您可以存储指向连接对象的指针并随时向客户端发送通知。

但它仍然有很多问题,我不建议在生产代码中使用这个 API。 您可以在此处看到 C++ 回调实现的当前进度:https://github.com/grpc/grpc/projects/12#card-12554506

【讨论】:

C++ 中的流式 grpc 是否提供这样的回调? 没有。使用流媒体,您不能在服务器上存储连接提供程序。使用 C++ 的当前实现,您只能通过下一个方案工作:客户端发出请求 -> 服务器接收它并准备一个答案。 -> 服务器使用最后一个包发送回复 - “完成”命令 -> TCP 连接关闭(并且无法保存以备将来使用)

以上是关于检测在 grpc 服务器中关闭的客户端连接的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 Kestrel 中的连接关闭

如何在 gRPC 中从服务器到客户端进行广播?

gRPC 客户端不使用服务器端流

grpc源码分析之域名解析

如何不从 C++ 连接到 gRPC C++ InProcessChannel?

如何在 Spring Boot 应用程序中关闭客户端 sse 连接