Netty心跳检测机制
主要是用于服务端检测,客户端不显示
1. 服务端
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; 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 { NioEventLoopGroup boss = new NioEventLoopGroup(); NioEventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(boss, worker) .channel(NioServerSocketChannel.class) //为boss添加日志 .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); /** * IdleStateHandler( 处理空闲状态的处理类 long readerIdleTime, 表示在时间内未读,发送一个心跳检测包来检测是否连接 long writerIdleTime, 表示在时间内未写,发送一个心跳检测包来检测是否连接 long allIdleTime, 表示在时间内没有读写,发送一个心跳检测包来检测是否连接 TimeUnit unit)``````` 单位 当IdleStateHandler触发后,传递给管道下一个handler处理,通过调用下一个handler的userEventTiggered, 在该方法中去处理 */ pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS)); //自定义对空闲检测进一步处理的handler pipeline.addLast(new MyServerHandler()); } }); //启动服务,绑定端口 ChannelFuture channelFuture = serverBootstrap.bind(7000).sync(); //监控关闭端口 channelFuture.channel().closeFuture().sync(); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } }
2.服务端处理类
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 事件 */ @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); } } }
3.客户端
import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import java.util.Scanner; public class Client { private final String hostname; private final int port; public Client(String hostname, int port) { this.hostname = hostname; this.port = port; } public void run() throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(); try { //客户端启动项 Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group).channel(NioSocketChannel.class).handler( new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //解码器 pipeline.addLast("Decoder", new StringDecoder()); //编码器 pipeline.addLast("Encoder", new StringEncoder()); pipeline.addLast(new ClientHandler()); } }); //启动客户端去连接服务器端 ChannelFuture channelFuture = bootstrap.connect(hostname, port).sync(); //得到channel Channel channel = channelFuture.channel(); System.out.println("-------" + channel.localAddress() + "-------"); //客户输入信息 Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { String msg = sc.nextLine(); channel.writeAndFlush(msg + "\r\n"); } } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws InterruptedException { new Client("127.0.0.1", 7000).run(); } }
4.客户端处理类
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; public class ClientHandler extends SimpleChannelInboundHandler<String>{ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { //输出去除两端空格的字符串 System.out.println(msg.trim()); } }