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

  本文介绍了 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 {

  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

  }

}

  使用了 IdleStateHandler ,分别设置了读、写超时的时间,定义了一个 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);

    }

  }

}

  定义了心跳时,要发送的内容判断是否是 IdleStateEvent 事件,是则处理将心跳内容发送给客户端

服务器

  服务器代码比较简单,启动后侦听 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

效果

  20151106-heartbeat

源码

  见https://github.com/waylau/netty-4-user-guide-demos中 heartbeat包

作者:Java高级架构
链接:https://www.jianshu.com/p/770b2d5f40cd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/wxxujian/p/12708177.html

时间: 04-15

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

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

Netty 超时机制的介绍 Netty 的超时类型 IdleState 主要分为: ALL_IDLE : 一段时间内没有数据接收或者发送 READER_IDLE : 一段时间内没有数据接收 WRITER_IDLE : 一段时间内没有数据发送 在 Netty 的 timeout 包下,主要类有: IdleStateEvent : 超时的事件 IdleStateHandler : 超时状态处理 ReadTimeoutHandler : 读超时状态处理 WriteTimeoutHandler : 写超

关于Netty对于Channel超时机制缺陷的一点想法

我们看看ReadTimeoutHandler下面这个初始化方法,在初始化的时候做的一些事情,Netty的2个改进点我认为都在这里可以体现出来(下面红体): private void initialize(ChannelHandlerContext ctx) { // Avoid the case where destroy() is called before scheduling timeouts. // See: https://github.com/netty/netty/issues/1

基于Netty的IdleStateHandler实现Mqtt心跳

基于Netty的IdleStateHandler实现Mqtt心跳 IdleStateHandler解析 最近研究jetlinks编写的基于Netty的mqtt-client(https://github.com/jetlinks/netty-mqtt-client),总结若干知识点. Netty中,实现心跳机制较为简单,主要依赖于IdleStateHandler判断channel的读写超时. /** * Creates a new instance firing {@link IdleState

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

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

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

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

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