空闲状态的处理器
IdleStateHandler(3, 5, 7, TimeUnit.SECONDS)
readerIdleTime 多长时间没有读操作,就会发送心跳包检测是否连接
writerIdleTime 多长时间没有写操作,就会发送心跳包检测是否连接
allIdleTime 多长时间没有读写操作,就会发送心跳包检测是否连接
当IdleStateHandler触发就会传递给管道下一个Handler去处理,触发下一个Handler的UserEventTiggered,在该方法中去处理IdleStateEvent,读空闲,写空闲,读写空闲
服务端
public class Server {
private final int port;
public Server(int port) {
this.port = port;
}
public void run() {
//创建两个事件循环组,bossGroup只处理连接请求,workGroup处理客户端业务处理,交给bossGroup
//两个都是无线循环
//默认CPU核*2
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
//创建服务端启动对象,配置参数
ServerBootstrap bootstrap = new ServerBootstrap();
//用链式编程进行设置
bootstrap.group(bossGroup, workGroup)//设置两个线程组
.channel(NioServerSocketChannel.class)//使用NioSocketChannel作为服务器通道实现
.option(ChannelOption.SO_BACKLOG, 128)//设置线程队列个数
.childOption(ChannelOption.SO_KEEPALIVE, true)//设置保持活动连接状态
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
//IdleStateHandler 空闲状态的处理器
//readerIdleTime 多长时间没有读操作,就会发送心跳包检测是否连接
//writerIdleTime 多长时间没有写操作,就会发送心跳包检测是否连接
//allIdleTime 多长时间没有读写操作,就会发送心跳包检测是否连接
//当IdleStateHandler触发就会传递给管道下一个Handler去处理,触发下一个Handler的UserEventTiggered,在该方法中去处理IdleStateEvent,读空闲,写空闲,读写空闲
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS))
.addLast(new ServerHandler());//空闲处理Handler需要自定义
}
});//给workGroup的EventLoop对应的管道设置处理器
//启动服务器,绑定端口,生成ChannelFuture对象
ChannelFuture future = bootstrap.bind(port).sync();
//对关闭通道进行监听(非阻塞监听,异步模型)
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
new Server(666).run();
}
}
自定义处理
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
//evt向下转型
IdleStateEvent event = (IdleStateEvent) evt;
String eventType = null;
switch (event.state()) {
case READER_IDLE:
eventType = "读空闲";
break;
case WRITER_IDLE:
eventType = "写空闲";
break;
case ALL_IDLE:
eventType = "读写空闲";
ctx.channel().close();
break;
}
System.out.println(ctx.channel().remoteAddress() + eventType + "超时");
}
}
}