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

效果

时间: 2024-12-03 20:28:45

Netty 超时机制及心跳程序实现的相关文章

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

本文介绍了 Netty 超时机制的原理,以及如何在连接闲置时发送一个心跳来维持连接. Netty 超时机制的介绍 Netty 的超时类型 IdleState 主要分为: ALL_IDLE : 一段时间内没有数据接收或者发送 READER_IDLE :    一段时间内没有数据接收 WRITER_IDLE :     一段时间内没有数据发送 在 Netty 的 timeout 包下,主要类有: IdleStateEvent :     超时的事件 IdleStateHandler : 超时状态处理

【您还有心跳吗?超时机制分析 】

问题描述 在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超时时间,在这个时间内没发起任何请求的连接会被断开,以减少负载,节约资源.并且该机制一般都是在服务端实现,因为client强制关闭或意外断开连接,server端在此刻是感知不到的,如果放到client端实现,在上述情况下,该超时机制就失效了.本来这问题很普通,不太值得一提,但最近在项目中看到了该机制的一种糟糕的实现,故在此深入分析一下. 问题分析及解决方案 服务端一般会保持很多个连接,所以,一般是创

您还有心跳吗?超时机制分析(java)

问题描述 在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超时时间,在这个时间内没发起任何请求的连接会被断开,以减少负载,节约资源.并且该机制一般都是在服务端实现,因为client强制关闭或意外断开连接,server端在此刻是感知不到的,如果放到client端实现,在上述情况下,该超时机制就失效了.本来这问题很普通,不太值得一提,但最近在项目中看到了该机制的一种糟糕的实现,故在此深入分析一下. 问题分析及解决方案 服务端一般会保持很多个连接,所以,一般是创

netty实现客户端服务端心跳重连

使用netty实现客户端服务端心跳重连 前言: 公司的加密机调度系统一直使用的是http请求调度的方式去调度,但是会出现网络故障导致某个客户端或者服务端断线的情况,导致很多请求信息以及回执信息丢失的情况,接着我们抛弃了http的方式,改为Tcp的方式去建立客户端和服务器之间的连接,并且要去实现断线重连的功能,经过讨论后决定使用java中成熟的nio框架 – netty去解决这一系列的问题. 1.       netty简单介绍: 在百度中对netty的解释是: Netty是由JBOSS提供的一个

Android超时机制的处理(很不错)

由于手机端应用的响应,与当时的无线通信网络状况有很大的关联.而通信网络往往具有不稳定,延迟长的特点.所以,在我们的应用程序中,当我们请求网络的时候,超时机制的应用就显得特别重要. 超时机制主要有: 1.HTTP请求超时机制 2.Socket通信超时机制 HTTP请求超时机制 public static void main(String[] args){ long a=System.currentTimeMillis(); try{ URL myurl = new URL(“http://www.

python调用函数设置超时机制

有时候需要给函数设置超时机制,以防止它卡住我们的程序,这里可以用python的signal模块,signal模块可以实现程序内部的信号处理. # coding:utf8 import time import signal # 自定义超时异常 class TimeoutError(Exception): def __init__(self, msg): super(TimeoutError, self).__init__() self.msg = msg def time_out(interval

(HttpClient超时机制)timeout调度算法探讨

mark一下: HttpClient超时机制(安全问题处理:访问超大文件控制) 不过httpclient4开始好象没有MultiThreadedHttpConnectionManager这个类了,代替的应该是:PoolingHttpClientConnectionManager.

Java并发框架——AQS超时机制

AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性能,这时就需要用到超时机制.在JDK1.5之前还没有juc工具,当时的并发控制职能通过JVM内置的synchronized关键词实现锁,但对一些特殊要求却力不从心,例如超时取消控制.JDK1.5开始引入juc工具完美解决了此问题,而这正得益于并发基础框架AQS提供了超时的支持. 为了更精确地保证时间

C# Socket连接请求超时机制

作者:RazanPaul 译者:Todd Wei 原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx 介绍 您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时控制机制.因此,当服务器未处于监听状态,或者发生网络故障时,客户端连接请求会被迫等待很长一段时间,直到抛出异常.默认的等待时间长达20~30