基于Netty5.0案例八服务端心跳包
2015-10-23 16:23
323 查看
前言介绍:
本案例主要介绍服务端心跳包使用
本案例心跳包主要用于服务端在读、写、读写超时内做出的相应处理。
代码拿到手后可以最好测试下,事必躬亲,无论案例如何明白也得自己测试。
环境需求:【一下内容下文提供下载】
1、Java
1.1、jdk1.7
1.2、Eclipse
2、netty-all-5.0.0.Alpha1.jar
代码部分:
ChildChannelHandler.java
MyIdleHandler.java
MyServerHanlder.java
NettyServer.java
本案例主要介绍服务端心跳包使用
本案例心跳包主要用于服务端在读、写、读写超时内做出的相应处理。
代码拿到手后可以最好测试下,事必躬亲,无论案例如何明白也得自己测试。
环境需求:【一下内容下文提供下载】
1、Java
1.1、jdk1.7
1.2、Eclipse
2、netty-all-5.0.0.Alpha1.jar
代码部分:
ChildChannelHandler.java
import java.nio.charset.Charset; import java.util.concurrent.TimeUnit; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.FixedLengthFrameDecoder; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.CharsetUtil; public class ChildChannelHandler extends ChannelInitializer{ @Override protected void initChannel(SocketChannel e) throws Exception { System.out.println("报告"); System.out.println("信息:有一客户端链接到本服务端"); System.out.println("IP:" + e.localAddress().getHostName()); System.out.println("Port:" + e.localAddress().getPort()); System.out.println("报告完毕"); /** * 心跳包 * 1、readerIdleTimeSeconds 读超时时间 * 2、writerIdleTimeSeconds 写超时时间 * 3、allIdleTimeSeconds 读写超时时间 * 4、TimeUnit.SECONDS 秒[默认为秒,可以指定] */ e.pipeline().addLast(new IdleStateHandler(2, 2, 2)); // 基于换行符号解码器 e.pipeline().addLast(new LineBasedFrameDecoder(1024)); // 解码转String e.pipeline().addLast(new StringDecoder(Charset.forName("GBK"))); // 编码器 String e.pipeline().addLast(new StringEncoder(Charset.forName("GBK"))); // 处理心跳 【放在编码解码的下面,因为这个是通道有处理顺序】 e.pipeline().addLast(new MyIdleHandler()); // 在管道中添加我们自己的接收数据实现方法 e.pipeline().addLast(new MyServerHanlder()); } }
MyIdleHandler.java
import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; public class MyIdleHandler extends ChannelHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent e = (IdleStateEvent) evt; if (e.state() == IdleState.READER_IDLE) { System.out.println("--- Reader Idle ---"); ctx.writeAndFlush("读取等待:客户端你在吗... ...\r\n"); // ctx.close(); } else if (e.state() == IdleState.WRITER_IDLE) { System.out.println("--- Write Idle ---"); ctx.writeAndFlush("写入等待:客户端你在吗... ...\r\n"); // ctx.close(); } else if (e.state() == IdleState.ALL_IDLE) { System.out.println("--- All_IDLE ---"); ctx.writeAndFlush("全部时间:客户端你在吗... ...\r\n"); } } } }
MyServerHanlder.java
import java.util.Date; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.bytes.ByteArrayDecoder; public class MyServerHanlder extends ChannelHandlerAdapter{ /* * channelAction * * channel 通道 * action 活跃的 * * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据 * */ public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().localAddress().toString()+" channelActive"); //通知您已经链接上客户端 String str = "您已经开启与服务端链接"+" "+ctx.channel().id()+new Date()+" "+ctx.channel().localAddress(); ctx.writeAndFlush(str); } /* * channelInactive * * channel 通道 * Inactive 不活跃的 * * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据 * */ public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().localAddress().toString()+" channelInactive"); } /* * channelRead * * channel 通道 * Read 读 * * 简而言之就是从通道中读取数据,也就是服务端接收客户端发来的数据 * 但是这个数据在不进行解码时它是ByteBuf类型的后面例子我们在介绍 * */ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //注意此处已经不需要手工解码了 System.out.println(ctx.channel().id()+""+new Date()+" "+msg); //通知您已经链接上客户端[给客户端穿回去的数据加个换行] String str = "服务端收到:"+ctx.channel().id()+new Date()+" "+msg+"\r\n"; //发送给客户端【可以开启关闭用于测试心跳包】 ctx.writeAndFlush(str); } /* * channelReadComplete * * channel 通道 * Read 读取 * Complete 完成 * * 在通道读取完成后会在这个方法里通知,对应可以做刷新操作 * ctx.flush() * */ public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } /* * exceptionCaught * * exception 异常 * Caught 抓住 * * 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接 * */ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println("异常信息:\r\n"+cause.getMessage()); } }
NettyServer.java
package com.itstack.netty.idle; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; public class NettyServer { public static void main(String[] args) { try { System.out.println("服务端开启等待连接... ..."); new NettyServer().bing(7397); } catch (Exception e) { e.printStackTrace(); } } public void bing(int port) throws Exception{ EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workGroup); b.channel(NioServerSocketChannel.class); b.option(ChannelOption.SO_BACKLOG, 1024); b.childHandler(new ChildChannelHandler()); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }
相关文章推荐
- 《程序员面试金典》--输出二叉树中某一层的所有元素
- 细数Objective-C中的回调机制
- linux问题-Redis的安装以及常用命令
- 【爬虫之路】一点有关学习BeautifulSoup的笔记
- 一起做RGB-D SLAM (6)
- codeforces572D. Minimization
- 文件恢复
- 左右margin top问题百分比值
- 对象的创建和存在的时间
- c语言学习之基础知识点介绍(六):if和switch结构
- VC++ 动态生成 成组的 RadioButton 按钮组
- 思杰的雄心——软件定义的工作空间 推荐
- Delphi中的操作二进制文件的两个重要函数
- 领奖啦!第二期博客征文《从HelloWorld启航——说说那些年我们一起写过的代码》获奖名单揭晓
- 一起做RGB-D SLAM (5)
- 【扣丁学堂】让程序员的开发项目不再半途而废
- HTML文本编辑
- 杭电1048--输出输出格式控制
- Spring3.2.9 + JdbcTemplate 学习
- INFORMATION_SCHEMA.COLUMNS-表的字段信息