netty学习四:监听channel的读写空闲情况
来源:互联网 发布:js点击隐藏按钮 编辑:程序博客网 时间:2024/06/06 05:15
概述
netty提供了一个IdleStateHandler类,可以用监听channel的读写空闲状态。构造方法如下:
public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit) { }
1、当隔了readerIdleTime后,如果客户端未发送信息到服务端,那么会触发channel的读空闲。
2、当隔了writerIdleTime后,如果服务端未发送信息到客户端,那么会触发channel的写空闲。
服务端代码
package idle.server;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;public class ChannelIdleServer { public static void main(String[] args) throws InterruptedException { // 接收连接,但是不处理 EventLoopGroup parentGroup = new NioEventLoopGroup(); // 真正处理连接的group EventLoopGroup childGroup = new NioEventLoopGroup(); try { //加载Initializer ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(parentGroup, childGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) //这里的childHandler是服务于childGroup的,如果直接使用 //handler方法添加处理器,则是服务于parentGroup的 .childHandler(new ChannelIdleServerInitializer()); //绑定监听端口 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); } finally { parentGroup.shutdownGracefully(); childGroup.shutdownGracefully(); } }}package idle.server;import java.util.concurrent.TimeUnit;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.timeout.IdleStateHandler;public class ChannelIdleServerInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new IdleStateHandler(5, 7, 20,TimeUnit.SECONDS)); pipeline.addLast(new ChannelIdleServerHandler()); }}package idle.server;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.handler.timeout.IdleStateEvent;public class ChannelIdleServerHandler extends ChannelInboundHandlerAdapter{ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent idleStateEvent = (IdleStateEvent)evt; String eventType = null; 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); ctx.channel().close(); } }}
客户端代码
package idle.client;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import io.netty.bootstrap.Bootstrap;import io.netty.channel.Channel;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;public class ChannelIdleClient { public static void main(String[] args) throws InterruptedException, IOException { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { //加载Initializer Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .handler(new ChannelIdleInitializer()); //连接服务端 Channel channel = bootstrap.connect("localhost", 8899).sync().channel(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); for(;;) { channel.writeAndFlush(br.readLine() + "\r\n"); } } finally { eventLoopGroup.shutdownGracefully(); } }}package idle.client;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.DelimiterBasedFrameDecoder;import io.netty.handler.codec.Delimiters;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;public class ChannelIdleInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline(); //1、按照分隔符切割消息 pipeline.addLast(new DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter())); //2、socket编程中需要对字符串进行编码解码 pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); //3、添加自定义处理器 pipeline.addLast(new ChannelIdleClientHandler()); }}package idle.client;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class ChannelIdleClientHandler extends SimpleChannelInboundHandler<String>{ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); }}
可以利用这种机制来实现心跳,检测服务器是否挂掉了。
csdn code 路径
这个项目的源代码放置在csdn code上,欢迎访问。
netty_study
阅读全文
0 0
- netty学习四:监听channel的读写空闲情况
- Netty学习之旅------Netty Channel 概述
- netty学习之Channel接口
- 学习 java netty (三) -- Channel
- 管道的四种读写情况
- 《Netty学习》(三)Channel学习
- Netty:Channel
- Netty学习笔记(二) Channel和ChannelFuture
- NIO与Netty的Channel组件
- NIO与Netty的Channel组件
- Netty之Channel的继承关系
- Netty学习之NIO---通道Channel(一)
- netty源码学习三(channel、channelHandler、channelPipeline)
- muduo网络库学习(二)对套接字和监听事件的封装Channel
- netty-channel-channelPipeline
- Netty教程-Channel
- netty学习(四)----伪异步IO的弊端
- Netty4 学习笔记之四: Netty HTTP服务的实现
- Builder模式
- 在IoC容器中装配Bean
- 【C#】 WinForm 中 MessageBox的使用详解
- hdu5687
- Maven的简单使用
- netty学习四:监听channel的读写空闲情况
- 【hdu 1205】 吃糖果 (抽屉原理)
- jhipster框架学习(三)
- C++详解Leetcode:103. Binary Tree Zigzag Level Order Traversal
- 2017-07-30 DBA日记,MYSQL读书笔记第二天
- Windows远程桌面连接使用教程
- 睡眠专家的7个建议 让你一夜好眠
- ccf认证数列分段
- Fragment初识(三)