运行效果
让Server端设置读空闲时间为5秒,写空间时间为7秒,读写空闲时间为13秒。
源码
Server
public class IdleServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new IdleServerInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(40000).sync();
channelFuture.channel().closeFuture().sync();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
class IdleServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
/**
* IdleStateHandler是处理空闲状态的处理器。
* readerIdleTime: 读空闲时间。超过此时间发送心跳检测是否连接状态
* writerIdleTime: 写空闲时间。超过此时间发送心跳检测是否连接状态
* allIdleTime: 读写空闲事件。超过此时间发送心跳检测是否连接状态
*/
pipeline.addLast(new IdleStateHandler(5,7,13, TimeUnit.SECONDS));
/**
* 如果空闲事件触发,调用IdleServerHandler的userEventTriggered方法。
*/
pipeline.addLast(new IdleServerHandler());
}
}
class IdleServerHandler extends ChannelInboundHandlerAdapter{
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if(evt instanceof 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);
//ctx.channel().close(); //如果发生空闲,关闭通道
}
}
}
Client
public class IdleClient {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ChatClientInitializer());
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1",40000).sync();
//channelFuture.channel().closeFuture().sync();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
channelFuture.channel().writeAndFlush(br.readLine()+"\r\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
eventLoopGroup.shutdownGracefully();
}
}
}
class IdleClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("client接收到信息:" + msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
class IdleClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(4096, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new ChatClientHandler());
}
}