在 Java 网络编程中,“心跳(Heartbeat)”通常用于检测连接是否存活、保持长连接不被中间设备(如 NAT、防火墙)断开,以及及时感知对端异常下线。
下面从原理 → 常见实现方式 → 示例代码 → 注意事项系统性说明。
心跳本质上就是:
客户端或服务端定期发送一个小数据包,对方收到后回复一个确认包
如果在规定时间内:
就认为连接已断开,进行重连或释放资源。
思路
Socket / ServerSocket"PING")"PONG"适用场景
缺点
WebSocket 本身支持长连接,常配合:
ping / pong 帧| 框架 | 心跳支持 |
|---|---|
| Netty | IdleStateHandler |
| gRPC | keepAlive |
| OkHttp | pingInterval |
| Spring WebSocket | 内置 |
Socket socket = new Socket("127.0.0.1", 8080);
socket.setSoTimeout(5000); // 读超时
BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 心跳线程
new Thread(() -> {
try {
while (true) {
writer.write("PING\n");
writer.flush();
Thread.sleep(3000); // 每 3 秒一次
}
} catch (Exception e) {
System.out.println("连接断开");
}
}).start();
String line = reader.readLine();
if ("PING".equals(line)) {
writer.write("PONG\n");
writer.flush();
}
如果:
readLine() 超时➡ 判定连接失效
pipeline.addLast(new IdleStateHandler(0, 0, 10));
pipeline.addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof IdleStateEvent) {
System.out.println("心跳超时,关闭连接");
ctx.close();
}
}
});
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.executor().scheduleAtFixedRate(() -> {
ctx.writeAndFlush("PING");
}, 0, 5, TimeUnit.SECONDS);
}
✅ Netty 是生产环境首选
| 参数 | 建议 |
|---|---|
| 心跳间隔 | 10–30 秒 |
| 超时次数 | 2–3 次 |
| 心跳包大小 | 越小越好 |
| 双向检测 | 客户端 + 服务端 |
❌ 只靠 TCP 的 keepalive
❌ 心跳太频繁
❌ 忘记处理异常断线
Java 网络心跳 = 定时小包 + 超时判断 + 断线处理
如果你愿意,我可以:
你现在是哪种使用场景?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。