Netty 心跳机制示例 —— 服务端实现

Netty 心跳机制示例 —— 服务端实现

1. 背景

在分布式系统和网络通信中,保持客户端与服务器端的连接活跃是非常重要的。如果长时间没有数据传输,连接可能会超时或被中断。为了解决这个问题,我们可以通过 心跳机制 来保证连接持续有效。

Netty 提供了强大的 IdleStateHandler 来实现心跳机制,它可以根据连接的空闲时间来主动检查连接状态,保证连接的健康。

2. 心跳机制介绍

在 Netty 中,心跳机制的核心组件是 IdleStateHandler,它会监测连接的读空闲(READ_IDLE)、写空闲(WRITE_IDLE)和读写空闲(ALL_IDLE)状态。当触发这些空闲状态时,Netty 会生成一个 IdleStateEvent 事件,并交由相应的处理器来处理(通常是发送心跳包或关闭连接等)。

3. 代码结构
1) 服务端实现
package netty.heartBeat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class MyServer {
    public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO)) // 添加日志处理器
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();

                            /**
                             * IdleStateHandler 是 Netty 提供的用于处理空闲状态的处理器
                             * 1. 多长时间没有读,会发送一个心跳检测包
                             * 2. 多长时间没有写,会发送一个心跳检测包
                             * 3. 多长时间没有读写,会发送一个心跳检测包
                             * IdleStateEvent 触发后会传递给下一个 handler 的 userEventTriggered 来处理
                             */
                            pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS)); // 配置空闲状态检测
                            pipeline.addLast(new MyServerHandler()); // 自定义处理器
                        }
                    });

            ChannelFuture sync = bootstrap.bind(7001).sync(); // 启动服务器并绑定端口
            sync.channel().closeFuture().sync(); // 等待关闭事件

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

主要功能:

  • 通过 ServerBootstrap 启动服务器并配置事件循环组(bossGroup 和 workerGroup)。

  • childHandler
    

    中配置了

    IdleStateHandler
    

    ,用于监测空闲状态。

    • IdleStateHandler(3, 5, 7, TimeUnit.SECONDS):表示 3 秒无读事件,5 秒无写事件,7 秒无读写事件,分别触发空闲事件。
  • 添加了自定义的 MyServerHandler,用于处理空闲状态事件。

2) 事件处理器
package netty.heartBeat;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;


public class MyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        if (evt instanceof IdleStateEvent) {
            // 将 evt 转型为 IdleStateEvent
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType = null;

            // 判断空闲状态类型
            switch (event.state()) {
                case READER_IDLE:
                    eventType = "读空闲";
                    break;
                case WRITER_IDLE:
                    eventType = "写空闲";
                    break;
                case ALL_IDLE:
                    eventType = "读写空闲";
                    break;
            }

            System.out.println(ctx.channel().remoteAddress() + "-- 超时时间发送 " + eventType);
            System.out.println("server do sth to solve");
        }
    }
}

主要功能:

  • MyServerHandler 继承自 ChannelInboundHandlerAdapter,重写 userEventTriggered 方法,用于处理 IdleStateEvent
  • 根据空闲状态(读空闲、写空闲、读写空闲)打印不同的日志信息,表示客户端连接处于哪种空闲状态。
4. 核心组件解析
  1. IdleStateHandler:Netty 提供的专门处理空闲状态的处理器。它会定期检查连接的空闲状态,并触发 IdleStateEvent 事件。IdleStateEvent 事件包含三个状态:
    • READER_IDLE:读空闲状态(长时间没有读取数据)。
    • WRITER_IDLE:写空闲状态(长时间没有写入数据)。
    • ALL_IDLE:读写空闲状态(长时间没有读写数据)。
  2. ChannelHandlerContext:表示一个通道的上下文对象,包含了通道的相关信息,并可以用于触发事件或写入数据。
  3. ChannelPipeline:用于存储和管理多个 ChannelHandler,执行链式调用。每个 ChannelHandler 负责处理不同类型的事件。
  4. ChannelInboundHandlerAdapterChannelInboundHandlerAdapter 是 Netty 提供的一个适配器类,允许你只重写需要的处理方法。我们继承此类并重写 userEventTriggered 方法来处理 IdleStateEvent
5. 心跳机制的工作流程
  1. 客户端和服务器建立连接。
  2. 服务器端通过 IdleStateHandler 配置空闲时间检测。
  3. 当连接空闲超过设置的时间限制时,IdleStateHandler 会触发 IdleStateEvent
  4. MyServerHandler 处理该事件,根据不同的空闲状态打印日志或执行其他操作(如发送心跳包)。
  5. 服务器保持与客户端的活跃连接,避免因空闲超时断开连接。
6.结果

image-20241206145909483

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值