文档章节

Netty 超时机制及心跳程序实现

waylau
 waylau
发布于 2015/11/06 21:42
字数 708
阅读 1116
收藏 22

本文同步至 http://www.waylau.com/netty-time-out-and-heartbeat/

本文介绍了 Netty 超时机制的原理,以及如何在连接闲置时发送一个心跳来维持连接。

Netty 超时机制的介绍

Netty 的超时类型 IdleState 主要分为:

  • ALL_IDLE : 一段时间内没有数据接收或者发送
  • READER_IDLE : 一段时间内没有数据接收
  • WRITER_IDLE : 一段时间内没有数据发送

在 Netty 的 timeout 包下,主要类有:

  • IdleStateEvent : 超时的事件
  • IdleStateHandler : 超时状态处理
  • ReadTimeoutHandler : 读超时状态处理
  • WriteTimeoutHandler : 写超时状态处理

其中 IdleStateHandler 包含了读\写超时状态处理,比如

private static final int READ_IDEL_TIME_OUT = 4; // 读超时
private static final int WRITE_IDEL_TIME_OUT = 5;// 写超时
private static final int ALL_IDEL_TIME_OUT = 7; // 所有超时

new IdleStateHandler(READ_IDEL_TIME_OUT,
			WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS));	

上述例子,在 IdleStateHandler 中定义了读超时的时间是 4 秒, 写超时的时间是 5 秒,其他所有的超时时间是 7 秒。

应用 IdleStateHandler

既然 IdleStateHandler 包括了读\写超时状态处理,那么很多时候 ReadTimeoutHandler 、 WriteTimeoutHandler 都可以不用使用。定义另一个名为 HeartbeatHandlerInitializer 的 ChannelInitializer :

public class HeartbeatHandlerInitializer extends ChannelInitializer<Channel> {

	private static final int READ_IDEL_TIME_OUT = 4; // 读超时
	private static final int WRITE_IDEL_TIME_OUT = 5;// 写超时
	private static final int ALL_IDEL_TIME_OUT = 7; // 所有超时

	@Override
	protected void initChannel(Channel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,
				WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS)); // 1
		pipeline.addLast(new HeartbeatServerHandler()); // 2
	}
}
  1. 使用了 IdleStateHandler ,分别设置了读、写超时的时间
  2. 定义了一个 HeartbeatServerHandler 处理器,用来处理超时时,发送心跳

定义了一个心跳处理器

public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter {
	
	// Return a unreleasable view on the given ByteBuf
	// which will just ignore release and retain calls.
	private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled
			.unreleasableBuffer(Unpooled.copiedBuffer("Heartbeat",
					CharsetUtil.UTF_8));  // 1

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
			throws Exception {

		if (evt instanceof IdleStateEvent) {  // 2
			IdleStateEvent event = (IdleStateEvent) evt;  
			String type = "";
			if (event.state() == IdleState.READER_IDLE) {
				type = "read idle";
			} else if (event.state() == IdleState.WRITER_IDLE) {
				type = "write idle";
			} else if (event.state() == IdleState.ALL_IDLE) {
				type = "all idle";
			}

			ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate()).addListener(
					ChannelFutureListener.CLOSE_ON_FAILURE);  // 3
 
			System.out.println( ctx.channel().remoteAddress()+"超时类型:" + type);
		} else {
			super.userEventTriggered(ctx, evt);
		}
	}
}
  1. 定义了心跳时,要发送的内容
  2. 判断是否是 IdleStateEvent 事件,是则处理
  3. 将心跳内容发送给客户端

服务器

服务器代码比较简单,启动后侦听 8082 端口

public final class HeartbeatServer {

    static final int PORT = 8082;

    public static void main(String[] args) throws Exception {

        // 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 HeartbeatHandlerInitializer());

            // Start the server.
            ChannelFuture f = b.bind(PORT).sync();

            // Wait until the server socket is closed.
            f.channel().closeFuture().sync();
        } finally {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

客户端测试

客户端用操作系统自带的 Telnet 程序即可:

telnet 127.0.0.1 8082

效果

源码

https://github.com/waylau/netty-4-user-guide-demosheartbeat

参考

© 著作权归作者所有

waylau

waylau

粉丝 528
博文 105
码字总数 185862
作品 2
深圳
架构师
私信 提问
Netty实现高性能、高可靠、可定制和可扩展分析

Netty如何实现高性能? 性能是设计出来的,不是测试出来的。Netty采用如下设计实现高性能: 采用异步非阻塞的I/O类库,基于Reactor模式实现,解决了传统同步阻塞I/O模式下一个服务端无法平滑...

宸明
2018/09/08
59
0
Netty系列之Netty高可靠性原理分析

背景 1.1. 宕机的代价 1.1.1. 电信行业 毕马威国际(KPMG International)在对46个国家的74家运营商进行调查后发现,全球通信行业每年的收益流失约为400亿美元,占总收入的1%-3%。导致收益流失...

tantexian
2016/07/22
207
0
Netty 那些事儿 ——— 心跳机制

本文是Netty文集中“Netty 那些事儿”系列的文章。主要结合在开发实战中,我们遇到的一些“奇奇怪怪”的问题,以及如何正确且更好的使用Netty框架,并会对Netty中涉及的重要设计理念进行介绍...

tomas家的小拨浪鼓
2017/11/11
0
0
Netty4(十一):实现心跳机制

案例代码下载 Netty 超时机制介绍 Netty 为超时机制提供了几个关键类: 编写超时状态处理 添加 IdleStateHandler 与 HeartbeatServerHandler 至 ChannelHandler 链 编写心跳处理器,判断是否...

林塬
2018/03/24
0
0
netty 服务端往客户端重发消息是怎么做到的?

关于netty 有没有对消息的超时与重传机制处理? 比如说 服务端发送一条查询消息到客户端,客户端没有应答这条查询消息,但是期间保持了心跳,发送了别的类型的数据给服务端。 此刻服务端应该...

别人家的老公1987
2018/10/17
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

家庭作业——苗钰婷

2 编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound, Sally shouted, "By the Great Pumpkin, what was that! #include<stdio.h>int main(){......

OSC_Okruuv
33分钟前
5
0
经典系统设计面试题解析:如何设计TinyURL(一)

原文链接: https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
35分钟前
4
0
2.面向对象设计原则(7条)

开闭原则 开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 实现方法 可以通过“抽象约束、封装变化”来实...

Eappo_Geng
37分钟前
8
0
8086汇编基础 debug P命令 一步完成loop循环

    IDE : Masm for Windows 集成实验环境 2015     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   ......

志成就
41分钟前
7
0
使用nodeJS实现前端项目自动化之项目构建和文件合并

本文转载于:专业的前端网站➜使用nodeJS实现前端项目自动化之项目构建和文件合并 前面的话   一般地,我们使用构建工具来完成项目的自动化操作。本文主要介绍如何使用nodeJS来实现简单的项...

前端老手
54分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部