服务器和客户端需要进行维护,netty提供了心跳检测机制
特殊代码标注
new LoggingHandler(LogLevel.INFO) // 日志级别添加,添加后netty会打印日志
readerIdleTime 读空闲事件 writerIdleTime写空闲时间 allIdleTime既没有读也没有写的时间
IdleStateHandler 处理空闲状态的时间检测,通过这个可以触发一个IdelStateEvent事件 ,当没有执行读写或者读写事件的时候就会触发。
IdleStateHandler 触发后 通过调用userEventTiggered 来进行业务处理
new IdleStateHandler(3,5,7, TimeUnit.SECONDS)
区分 IdleStateHandler handlerRemoved
IdleStateHandler 能够实时触发,可以在保持连接的时候,来检测到连接的一个状态。
handlerRemoved 只能检测服务关闭的过程。
最终通过自定义的handler 来触发心跳的事件 ,通过下一个pipline来处理
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
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 HeartBeatServer {
private final int prot = 9999;
public void run () throws Exception{
ServerBootstrap serverBootstrap = new ServerBootstrap();
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try{
serverBootstrap.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// 定义包
pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));
//自定义pipline
pipeline.addLast( new MyselfHeartBeatHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(prot).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new HeartBeatServer().run();
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
public class MyselfHeartBeatHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
// 判断是否是 IdeState类型
if(evt instanceof IdleStateEvent){
IdleStateEvent event = (IdleStateEvent) evt;
String eventState =null;
switch (event.state()){
case ALL_IDLE:
eventState="读写空闲";
break;
case READER_IDLE:
eventState="读空闲";
break;
case WRITER_IDLE:
eventState="写空闲";
break;
}
System.out.println(ctx.channel().remoteAddress()+"发生"+eventState);
}
}
}