使用 Java 实现 keepalive
我正在构建一个客户端-服务器应用程序,我必须在其中实现保活机制才能检测客户端是否崩溃。我在客户端和服务器端都有单独的线程。客户端线程发送“ping”,然后休眠 3 秒,同时服务器读取 BufferedInputStream 并检查是否收到 ping,如果是,则使 ping 计数器等于 0,否则将计数器增加+1,服务器线程然后休眠3秒,如果ping计数器达到3,则声明客户端已死亡。
问题是,当服务器读取输入流时,它是一个阻塞调用,并且它会阻塞直到收到下一个 ping,无论延迟有多大,因此服务器永远不会检测到丢失的 ping。
任何建议,以便我可以读取流的当前值,并且如果传入流上没有任何内容,它不会阻塞。
谢谢,
I am building a client-server application where I have to implement a keepalive mechanism in order to detect that the client has crashed or not. I have separate threads on both client and server side. the client thread sends a "ping" then sleeps for 3 seconds, while the server reads the BufferedInputStream
and checks whether ping is received, if so it makes the ping counter equals zero, else it increments the counter by +1, the server thread then sleeps for 3 seconds, if the ping counter reaches 3, it declares the client as dead.
The problem is that when the server reads the input stream, its a blocking call, and it blocks until the next ping is received, irrespective of how delayed it is, so the server never detects a missed ping.
any suggestions, so that I can read the current value of the stream and it doesn't block if there is nothing on the incoming stream.
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Java 1.4 引入了非阻塞 I/O 的思想,以 java.nio 包为代表。这可能就是您所需要的。
请参阅本教程如何使用非阻塞 I/O。
另外,假设这不是家庭作业或学习练习,那么我建议使用更强大的协议框架,例如 Apache Mina< /a> 或 JBoss Netty,而不是从头开始构建这些东西。请参阅它们之间的比较,以及为什么要使用它们。
Java 1.4 introduced the idea of non-blocking I/O, represented by the
java.nio
package. This is probably what you need.See this tutorial for how to use non-blocking I/O.
Also, assuming this isn't homework or a learning exercise, then I recommend using a more robust protocol framework such as Apache Mina or JBoss Netty, rather than building this stuff from scratch. See this comparison between them, and why you'd want to use them.
您可以有一个单独的监视线程来监视所有阻塞连接。当连接接收到任何内容时,它可以重置计数器。 (我会将任何数据包视为心跳)您的监视线程可以在每次运行时增加此计数器,并且当它达到限制时(即因为它没有重置回零)您可以关闭连接。您只需要一个这样的线程。阻塞在您刚刚关闭的连接上的线程抛出 IOException,唤醒该线程。
另一方面,只要一段时间内没有发送数据包,就可以触发心跳。这意味着繁忙的连接不会发送任何心跳,也不需要发送任何心跳。
You can have a separate monitoring thread which monitors all the blocking connections. When a connection receives anything it can reset a counter. (I would treat any packet as good as a heartbeat) Your monitoring thread can increment this counter each times it runs and when it reaches a limit (i.e. because it wasn't reset back to zero) you can close the connection. You only need one such thread. The thread which is blocking on the connection you just closed with throw an IOException, waking the thread.
On the other side, a heartbeat can be triggered whenever a packet has not been sent for some period of time. This mean a busy connection doesn't send any heartbeats, it shouldn't need to.