import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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 MyServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workGroup).channel(
NioServerSocketChannel.class).
//在 bossGroup 增加一个日志处理器
handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
//添加一个idleHandler
// IdleStateHandler处理空闲状态的处理器
//long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit)
//readerIdleTime server没有读取客户端的数据 发送一个心跳检测包 是否连接状态
//writerIdleTime server没有写输数据给客户端
//allIdleTime server没有读写数据 发送心跳给客户端
//IdleStateHandler 事件触发后就会传递给管道的下一个handler,通过调用下一个handler的
//userEventTrigger方法中去处理对应的事件 读,写,读写
.addLast(new IdleStateHandler(3,5,7,
TimeUnit.SECONDS))
.addLast(new MyServerHandler());
//加入对空闲检测处理自定义handler
}
});
ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
/**
*
*/
public class MyServerHandler extends ChannelInboundHandlerAdapter {
/**
* 发生心跳事件的时候,触发下面这个方法
* @param ctx
* @param evt
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx,
Object evt) throws Exception {
if(evt instanceof IdleStateEvent){
IdleStateEvent idleStateEvent=(IdleStateEvent)evt;
String eventType="";
switch (idleStateEvent.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("服务器做相应的处理");
//如果发生空闲 则关闭通道一次
ctx.channel().close();
}
}
}