一、前言
心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。
我们用到的很多框架都用到了心跳检测,比如服务注册到 Eureka Server 之后会维护一个心跳连接,告诉 Eureka Server 自己还活着。本文就是利用 Netty 来实现心跳检测,以及客户端重连。
二、设计思路
- 分为客户端和服务端
- 建立连接后,客户端先发送一个消息询问服务端是否可以进行通信了。
- 客户端收到服务端 Yes 的应答后,主动发送心跳消息,服务端接收到心跳消息后,返回心跳应答,周而复始。
- 心跳超时利用 Netty 的 ReadTimeOutHandler 机制,当一定周期内(默认值50s)没有读取到对方任何消息时,需要主动关闭链路。如果是客户端,重新发起连接。
- 为了避免出现粘/拆包问题,使用 DelimiterBasedFrameDecoder 和 StringDecoder 来处理消息。
三、编码
- 先编写客户端 NettyClient
public class NettyClient {
private static final String HOST = "127.0.0.1";
private static final int PORT = 9911;
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
EventLoopGroup group = new NioEventLoopGroup();
private void connect(String host,int port){
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.remoteAddress(new InetSocketAddress(host,port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_", CharsetUtil.UTF_8);
ch.pipeline()
.addLast(new DelimiterBasedFrameDecoder(1024,delimiter))
.addLast(new StringDecoder())
// 当一定周期内(默认50s)没有收到对方任何消息时,需要主动关闭链接
.addLast("readTimeOutHandler",new ReadTimeoutHandler(50))
.addLast("heartBeatHandler",new