心跳机制的意义:

TCP空闲的时候是不会发送任何数据包。也就是说,当一个TCP的socket,客户端与服务端谁也不发送数据,会一直保持着连接。这其中如果有一方异常掉线(例如死机、路由被破坏、防火墙切断连接等),另一端如果没有发送数据,永远也不可能知道

。这对于一些服务型的程序来说,是灾难性的后果,将会导致服务端socket资源耗尽。

所以为了保证连接的有效性、及时有效地检测到一方的非正常断开,保证连接的资源被有效的利用,我们就会需要一种保活的机制,通常改机制两种处理方式:1、利用TCP协议层实现的Keepalive;2、自己在应用层实现心跳包。

两种方式的对比如下:

1、TCP协议自带的保活功能, 使用起来简单, 减少了应用层代码的复杂度. 更节省流量, 因为一般来说应用层的数据传输到协议层时都会被加上额外的包头包尾. 由TCP协议提供的检活, 其发的ACK包比应用层的心跳包耗费更少的流量。

2、应用层心跳包相对与Keepalive更灵活,因为协议层的心跳只能提供最纯粹的检活功能, 但是应用层自己可以随意控制,甚至加入一些额外逻辑。

3、应用层心跳包相对与Keepalive更灵活,应用层心跳包不依赖于协议,如若有一天不用TCP要改为UDP了,只需做少量改动甚至不用改动即可实现转换。

因此,作为通信框架的Netty,应用层实现心跳机制还是很有必要的。

Netty3实现心跳事件处理实例

1. 在pipeline属性中加入心跳检测机制,代码如下:

pipeline.addLast("idle",new IdleStateHandler(hashedWheelTimer,5,5,10));

这段代码表示设置心跳检测的时间间隔

2. 添加处理心跳的业务逻辑处理类:

pipeline.addLast("helloHandler",new HelloHandler());

3. 实现业务逻辑处理类,继承于SimpleChannelHandler;实现代码如下:

public class HelloHandler extends SimpleChannelHandler {@Overridepublic void messageReceived(ChannelHandlerContext ctx, MessageEvent e){System.out.println(e.getMessage());}@Overridepublic void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e)  throws Exception{if(e instanceof IdleStateEvent){if(((IdleStateEvent)e).getState() == IdleState.ALL_IDLE) {System.out.println("踢玩家下线");//关闭会话 踢玩家下线ChannelFuture write=ctx.getChannel().write("time out, you will close");write.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture channelFuture) throws Exception {ctx.getChannel().close();}});}}else{super.handleUpstream(ctx,e);}}
}

Netty5实现心跳处理事件实例

实现流程跟Netty3的实现流程类似,首先在pipeline属性中加入心跳检测机制和心跳的业务逻辑处理类,代码如下:

bootstrap.childHandler(new ChannelInitializer<Channel>() {protected  void initChannel(Channel ch) throws Exception{ch.pipeline().addLast(new IdleStateHandler(5,5,10));ch.pipeline().addLast("decoder",new StringDecoder());ch.pipeline().addLast("encoder",new StringEncoder());ch.pipeline().addLast(new ServerHandler());}});

实现心跳业务逻辑处理类,Netty5的继承类和Netty3有所不同,Netty5是继承于SimpleChannelInboundHandler,代码如下:

protected void messageReceived(ChannelHandlerContext ctx,String msg) throws  Exception{System.out.println(msg);ctx.channel().writeAndFlush("hi");ctx.writeAndFlush("hi");}public void userEventTriggered(final ChannelHandlerContext ctx,Object evt)  throws Exception{if(evt instanceof IdleStateEvent){IdleStateEvent event=(IdleStateEvent)evt;if(event.state()== IdleState.ALL_IDLE){//清除超时会话ChannelFuture writeAndFlush=ctx.writeAndFlush("you will close");writeAndFlush.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture channelFuture) throws Exception {ctx.channel().close();}});}}else{super.userEventTriggered(ctx,evt);}}

Netty学习06-用Netty3和Netty5分别写一个心跳处理实例相关推荐

  1. 从零开始学习linux的I2C设备驱动框架——写一个简单的SHT20驱动

    目录 0.测试环境说明 1.设备树的修改 2.设备驱动框架 3.I2C数据传输过程 3.1 struct i2c_msg 3.2 SHT20的数据收发 4.I2C适配器超时等待时间的修改 本文资源 参 ...

  2. ROS的学习(十六)用C++写一个简单的服务器(service)和客户端(client)

    我们将创建一个服务器节点add_two_ints_server,它将会收到两个整数,并且返回它们的和.切换目录到之前建立的beginner_tutorials包下: cd ~/catkin_ws/sr ...

  3. ROS的学习(十四)用C++写一个简单的接收者

    打开一个终端,进入到beginner_tutorials包下面: cd ~/catkin_ws/src/beginner_tutorials 编辑文件 src/listener.cpp: vim sr ...

  4. ROS的学习(十二)用C++写一个简单的发布者

    节点是一个可执行程序,它连接到了ROS的网络系统中.我们将会创建一个发布者,也就是说话者节点,它将会持续的广播一个信息. 改变目录到之前所建立的那个包下: cd ~/catkin_ws/src/beg ...

  5. 从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---11. MVC功能之http请求处理器的编写---简易框架最后一公里!

    从零写一个具有IOC-AOP-MVC功能的框架-学习笔记 专栏往期文章链接: IOC功能相关章节: 从零写一个具有IOC-AOP-MVC功能的框架-学习笔记-01.项目初始化 从零写一个具有IOC-A ...

  6. Netty学习笔记二网络编程

    Netty学习笔记二 二. 网络编程 1. 阻塞模式 阻塞主要表现为: 连接时阻塞 读取数据时阻塞 缺点: 阻塞单线程在没有连接时会阻塞等待连接的到达,连接到了以后,要进行读取数据,如果没有数据,还要 ...

  7. Netty学习笔记一NIO基础

    Netty学习笔记一 一. NIO 基础 non-blocking io 非阻塞IO (也可称为new IO, 因为是JDK1.4加入的) 1. 三大组件 1.1 Channel 通道:数据的传输通道 ...

  8. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  9. ThinkPhp学习06

    原文:ThinkPhp学习06 一.简单学习修改用户信息模块 1.编写UserAction.class.php 1 <?php 2 3 class UserAction extends Acti ...

最新文章

  1. ASP.NET页面借助IFrame提交表单数据所遇到的问题
  2. [LeetCode]: 53: Maximum Subarray
  3. 深度学习要点———神经网络的类型
  4. Wcf 接收对http://*.*.*.*的的 HTTP 响应时发生错误... 的解决方法
  5. Day 28: OpenShift的Eclipse集成
  6. 使用Sidecar支持异构平台的微服务
  7. java学习(65):类访问static修饰的内部类
  8. vbox虚拟机配置Redhat6.4本地yum源
  9. 计算机专业论文设计与实现,计算机专业论文 计算机网络的设计与实现.doc
  10. 初试Octave软件
  11. 欲练JS,必先攻CSS——前端修行之路
  12. 中电海康建车联网透明路 探索新型智慧城市商机
  13. 快速构建Windows 8风格应用25-数据绑定
  14. 线性调频信号及仿真[python]
  15. 模拟滑动窗口协议算法C语言,滑动窗口协议模拟程序.docx
  16. 雷达原理---时频分析--2.短时傅里叶变换
  17. LeetCode contest 182 5369. 统计作战单位数
  18. 用A*算法实现传道士野人渡河问题
  19. django获取cleaned_data属性失败
  20. xpath 爬取51job,存于excel

热门文章

  1. air什么意思中文_air是什么意思_air中文意思_air英译汉_英汉词典
  2. matlab高通滤波代码疑问
  3. Linux中各命令英文缩写的含义
  4. JavaScript生成二维数组
  5. 出海的中国企业,为什么有80%都选择了这家云服务商?
  6. 详解 OpenDAL |Data Infra 研究社第三期
  7. 一文搞懂Pandas Dataframe中的apply方法
  8. 2009年总结amp;amp;我在招商银行软件中心(融博)工作的日子
  9. dockerfile案例
  10. 联想Y50-70黑苹果Big Sur 11.01全过程,附EFI和镜像