Netty Client 重连实现

当我们用Netty实现一个TCP client时,我们当然希望当连接断掉的时候Netty能够自动重连。
Netty Client有两种情况下需要重连:

  1. Netty Client启动的时候需要重连
  2. 在程序运行中连接断掉需要重连。

对于第一种情况,Netty的作者在stackoverflow上给出了解决方案
对于第二种情况,Netty的例子uptime中实现了一种解决方案

而Thomas在他的文章中提供了这两种方式的实现的例子。

实现ChannelFutureListener 用来启动时监测是否连接成功,不成功的话重试:

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
public class Client 
 
   private EventLoopGroup loop = new NioEventLoopGroup(); 
   public static void main( String[] args ) 
   
     new Client().run(); 
   
   public Bootstrap createBootstrap(Bootstrap bootstrap, EventLoopGroup eventLoop) {  
     if (bootstrap != null) { 
       final MyInboundHandler handler = new MyInboundHandler(this); 
       bootstrap.group(eventLoop); 
       bootstrap.channel(NioSocketChannel.class); 
       bootstrap.option(ChannelOption.SO_KEEPALIVE, true); 
       bootstrap.handler(new ChannelInitializer<SocketChannel>() { 
         @Override 
         protected void initChannel(SocketChannel socketChannel) throws Exception { 
           socketChannel.pipeline().addLast(handler); 
         
       }); 
       bootstrap.remoteAddress("localhost"8888);
       bootstrap.connect().addListener(new ConnectionListener(this));
     
     return bootstrap; 
   
   public void run() { 
     createBootstrap(new Bootstrap(), loop);
   
 }

ConnectionListener 负责重连:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ConnectionListener implements ChannelFutureListener { 
  private Client client; 
  public ConnectionListener(Client client) { 
    this.client = client; 
  
  @Override 
  public void operationComplete(ChannelFuture channelFuture) throws Exception {  
    if (!channelFuture.isSuccess()) { 
      System.out.println("Reconnect"); 
      final EventLoop loop = channelFuture.channel().eventLoop(); 
      loop.schedule(new Runnable() { 
        @Override 
        public void run() { 
          client.createBootstrap(new Bootstrap(), loop); 
        
      }, 1L, TimeUnit.SECONDS); 
    
  
}

同样在ChannelHandler监测连接是否断掉,断掉的话也要重连:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyInboundHandler extends SimpleChannelInboundHandler { 
   private Client client; 
   public MyInboundHandler(Client client) { 
     this.client = client; 
   
   @Override 
   public void channelInactive(ChannelHandlerContext ctx) throws Exception {  
     final EventLoop eventLoop = ctx.channel().eventLoop(); 
     eventLoop.schedule(new Runnable() { 
       @Override 
       public void run() { 
         client.createBootstrap(new Bootstrap(), eventLoop); 
       
     }, 1L, TimeUnit.SECONDS); 
     super.channelInactive(ctx); 
   
 }

参考文档

  • http://stackoverflow.com/questions/19739054/whats-the-best-way-to-reconnect-after-connection-closed-in-netty
  • https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/uptime/UptimeClientHandler.java
  • http://tterm.blogspot.jp/2014/03/netty-tcp-client-with-reconnect-handling.html
  • ctx.close vs ctx.channel().close
  • ctx.write vs ctx.channel().write

原文地址:https://www.cnblogs.com/duanxz/p/3470613.html