Netty4与Netty3.x的心跳机制略有不同,在Netty4中已经去掉了IdleStateAwareChannelHandler这个类,但IdleStateHandler依旧保留,只是心跳超时的触发事件的写法略有不同,Netty底层实现了一套类似信号和槽的事件通信机制。

这里且看实现。

首先是在 SocketChannel.pipeline 中注册 IdleStateHandler 进行心跳时间的定制:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

// Configure the server.

EventLoopGroup bossGroup = new NioEventLoopGroup(1);

EventLoopGroup workerGroup = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class)

.option(ChannelOption.SO_BACKLOG, 100)

.handler(new LoggingHandler(LogLevel.INFO))

.childHandler(new ChannelInitializer() {

@Override

public void initChannel(SocketChannel ch)

throwsException{

ch.pipeline()

.addLast(

new LoggingHandler(LogLevel.INFO),

new IdleStateHandler(30,0,0),// 心跳控制

new ServerHandler());

}

});

// Start the server.

ChannelFuture f = b.bind(port).sync();

// Wait until the server socket is closed.

f.channel().closeFuture().sync();

} catch (InterruptedExceptione) {

e.printStackTrace();

} finally {

// Shut down all event loops to terminate all threads.

bossGroup.shutdownGracefully();

workerGroup.shutdownGracefully();

}

这里要注意IdleStateHandler()要放在ServerHandler()的前面,否则心跳管理无法触发ServerHandler中的userEventTriggered()方法。

此时已经成功在服务器中创建了心跳控制器:

IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds)

Property

Meaning

readerIdleTime

anIdleStateEventwhose state isIdleState.READER_IDLEwill be triggered when no read was performed for the specified period of time. Specify 0to disable.

writerIdleTime

anIdleStateEventwhose state isIdleState.WRITER_IDLEwill be triggered when no write was performed for the specified period of time. Specify 0 to disable.

allIdleTime

anIdleStateEventwhose state isIdleState.ALL_IDLEwill be triggered when neither read nor write was performed for the specified period of time. Specify 0 to disable.

这里readerIdleTime为读超时时间(即服务器一定时间内未接受到客户端消息)

writerIdleTime为写超时时间(即服务器一定时间内向客户端发送消息)

allIdleTime为全体超时时间(即同时没有读写的时间)

对于以上几种Time的使用根据用户自己的需求来决定。这里我们作为验证客户端心跳的机制,只需要设置readerIdleTime这一个参数就够了。

接下来我们需要在ServerHandler中实现其继承自ChannelInboundHandlerAdapter的userEventTriggered()方法来做心跳超时事件的触发实现,代码如下

ServerHandler.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

public class ServerHandler extends ChannelInboundHandlerAdapter {

...

@Override

public void channelRead(ChannelHandlerContext ctx,Objectmsg)

throwsException{

...

}

...

@Override

public void userEventTriggered(ChannelHandlerContext ctx,Objectevt)

throwsException{

/*心跳处理*/

if (evt instanceof IdleStateEvent) {

IdleStateEvent event = (IdleStateEvent) evt;

if (event.state() == IdleState.READER_IDLE) {

/*读超时*/

System.out.println("READER_IDLE 读超时");

ctx.disconnect();

} else if (event.state() == IdleState.WRITER_IDLE) {

/*写超时*/

System.out.println("WRITER_IDLE 写超时");

} else if (event.state() == IdleState.ALL_IDLE) {

/*总超时*/

System.out.println("ALL_IDLE 总超时");

}

}

}

}

@Override

public void channelInactive(ChannelHandlerContext ctx) throwsException{

// 这里加入玩家的掉线处理

ctx.close();

}

...

通过对IdleStateEvent的判断即可分别实现不同超时情况的处理,这里我们针对的是READER_IDLE的超时判断,因此在其判断成功后执行ctx.disconnect(),即关闭客户端连接。

此时会触发channelInactive()方法,我们将玩家的断线处理如保存玩家信息等内容写在channelInactive()中即可。

客户端主动断开的连接同理,均会触发其Channel所属的Handler中的channelInactive()方法。

以上即实现了一套简单的服务器心跳机制,只要保证客户端在每单位时间(这里设置的是30秒)发送一次消息给服务器即可保证其不被踢下线。

本篇到此,欢迎大家提出更优化的心跳机制实现方案。

谢谢关注。

转自:BeiTown's Coder 编码之源http://coder.beitown.com/archives/1180

这里也可以参考:http://blog.csdn.net/educast/article/details/47706863

评论

暂无评论!

昵  称:

验证码:

内  容:

打赏

微信扫一扫,打赏一下~

关注公众号

java通过netty实现心跳机制_Netty4服务端心跳机制相关推荐

  1. Netty 源码解析系列-服务端启动流程解析

    netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...

  2. 基于Redisson实现的延时队列RedissonDelayedQueue实现websocket服务端心跳监听

    简介 基于Redis的Redisson分布式延迟队列(Delayed Queue)结构的 RDelayedQueue. Java对象在实现了RQueue接口的基础上提供了向队列按要求延迟添加项目的功能 ...

  3. Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信

    本文计划采用socket实现客户端和服务端的任意双向通信,即客户端可以随时给服务端发消息,服务端也可以随时给客户端发消息,最终结果就是一个类似与QQ的聊天软件的功能. 以下代码可以直接拷贝到Eclip ...

  4. Java中利用socket实现简单的服务端与客户端的通信(基础级)

    在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程.上一篇文章的链接:Java中利用socket实现 ...

  5. Java中利用socket实现简单的服务端与客户端的通信(入门级)

    Java编程中,要想要使用网络通信,就离不开Socket编程,在此对socket进行简单的介绍.首先声明,这是一个入门级的介绍,仅仅简单的实现了客户端向服务端发送数据,服务端正常的接收数据,当接收到特 ...

  6. Netty简单实现客户端与服务端收发消息

    Netty简单实现客户端与服务端收发消息 这个小案例主要是实现netty收发消息,分为客户端,及服务端,以及包含了相关状态处理,主要的代码会放在最后 gitHub 地址上,有需要可以看一下 首先来简单 ...

  7. 采用netty开发智能手表tcp服务端还是非常不错的

    采用netty开发智能手表tcp服务端还是非常不错的,经过单服务部署测试并发能达到10w,可以用于开发开发马蹄锁,儿童智能手表,其他智能设备,物联网等等,有啥有趣好玩的物联网可以进行交流一下

  8. 利用netty开发webScoketClient(支持wss协议,客户端、服务端心跳实现)

    这里写目录标题 前言 题外话 webScoketClient实现方式一(jacva_webscoket) webScoketClient工具类 简单编写测试 webScoketClient实现方式二( ...

  9. 【Netty系列_3】Netty源码分析之服务端channel

    highlight: androidstudio 前言 学习源码要有十足的耐性!越是封装完美的框架,内部就越复杂,源码很深很长!不过要抓住要点分析,实在不行多看几遍,配合debug,去一窥优秀框架的精 ...

最新文章

  1. 再读《精通css》03:引入和注释
  2. 15:18 2009-7-5 小结
  3. 【Java从0到架构师,mysql视频教程推荐
  4. tomcat服务组件详解(二)
  5. 深入理解JavaScript系列(27):设计模式之建造者模式
  6. 解题报告 树形图计数
  7. 【数据结构】二叉树的遍历及应用
  8. 选择所有选项的多选复选框列表或复选框下拉列表
  9. (原)ubuntu下cadvisor+influxdb+grafana+supervisord监控主机和docker的containers
  10. 第 0 章 阳哥MySQL高级
  11. c语言课程设计做科普,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
  12. 什么是分布式查询mysql_基础普及之什么是分布式SQL
  13. 分享一份非常强势的Android面试题
  14. oracle定时任务按照小时,ORACLE定时任务时间间隔设置
  15. OpenWRT路由器-中继模式下无线接入
  16. flutter 生命周期源码解析
  17. Python乐趣之tkinter欢迎界面
  18. ultravnc 反向连接_C程序以反向显示链接列表
  19. 鲸探发布点评:7月7日发售陈孟昕系列绘画数字藏品
  20. 超声图像散斑去噪方法

热门文章

  1. 淘宝店铺基础优化细节 卖家忽略的店铺优化
  2. 学生信息管理系统之------书签(mybookmark)的作用
  3. Secure Federated Transfer Learning (论文翻译与拓展)
  4. NVIDIA VPI架构解析
  5. 程序员必须掌握的英文单词(二)
  6. notepad++下载和安装
  7. 如何重启或重置HomePod或HomePod mini?
  8. Sine Sweep(正弦扫频信号)
  9. java 级联删除_JavaEE中的级联删除讲解级源码
  10. 计算机网络基础这门课的介绍,课程介绍