ZMQ - 客户端服务器:客户端意外断电,服务器如何检测到?

ZMQ - Client Server: Client is powered off unexpectedly, how server detects it?

多个客户端连接到一个 ZMQ_PUSH 套接字。当客户端意外断电时,服务器不会收到警报并继续向其发送消息。尽管使用 ZMQ_OBLOCK 并将 ZMQ_HWM 设置为 5(最多仅排队 5 条消息),但除非重新连接客户端并且一次接收到队列中的所有消息,否则我的服务器不会收到错误消息。

zmq 中没有任何内容可以明确检测程序在套接字另一端的意外终止,或网络连接的无故和意外失败。

历史上一直有关于向 zmq 添加某种底层乒乓球“你还活着”的内部消息传递的讨论,但上次我查看时(很久以前)已经决定不这样做.

这确实意味着崩溃、网络故障等不一定会得到非常干净的处理,您的应用程序不一定知道发生了什么或消息是否已成功发送。毕竟是Actor模型。当您发现您的程序最终可能会确定之前出现的问题。 zmtp 中的超时会发现故障,最终后果会回到您的程序中。

要做得更好,您必须自己在上面放置类似乒乓球的东西(例如,为此设置一个单独的套接字,以便您可以跟踪客户端的可达性),但随后开始变得非常很难使用 ZMQ 的好部分,例如推/拉。这可能就是(优秀的)zmq 作者决定不把它放在自己身上的原因。

当遇到类似的问题时,我最终编写了自己的传输库。我找不到在面对网络故障、崩溃等情况下表现良好的现成产品。它实现了 CSP,而不是 actor 模型,不是非常快(不可避免),没有在 zmq 中做模式有道理,但确实意味着程序始终知道消息的确切位置,并且知道客户端始终处于活动状态或无法访问。 CSPness 还意味着消息传输是一个执行集合点,因此程序也知道彼此在做什么。

我最近 运行 在使用 ZMQ 时遇到了类似的问题。我们会切断互连系统的电源,用户将无法自动重新连接。事实证明,最近(过去一年左右)在 ZMTP(ZMQ 套接字使用的底层协议)上实现了心跳机制。

如果您使用的是 ZMQ 4.2.0 或更高版本,请查看设置 ZMQ_HEARTBEAT_IVL 和 ZMQ_HEARTBEAT_TIMEOUT 套接字选项 (http://api.zeromq.org/4-2:zmq-setsockopt)。这些将设置心跳之间的间隔 (ZMQ_HEARTBEAT_IVL) 以及在关闭连接之前等待回复的时间 (ZMQ_HEARTBEAT_TIMEOUT)。

编辑:您必须在连接前设置这些套接字选项。