from: http://www.dozer.cc/2015/05/netty-auto-reconnect.html

自动重连

用 Netty 写 Client 和 Server 的时候必须要去处理自动重连。

Server 端启动时的错误,要去不断重试。

Client 端不仅要处理启动时的错误,还要处理中途断开连接。

Server 端的处理

和常规的代码相比,Server 端只要处理一个地方即可:

public final class TcpServer {         private volatile EventLoopGroup bossGroup;      private volatile EventLoopGroup workerGroup;      private volatile ServerBootstrap bootstrap;      private volatile boolean closed = false;      private final int localPort;      public TcpServer(int localPort) {         this.localPort = localPort;     }      public void close() {         closed = true;          bossGroup.shutdownGracefully();         workerGroup.shutdownGracefully();          System.out.println("Stopped Tcp Server: " + localPort);     }      public void init() {         closed = false;          bossGroup = new NioEventLoopGroup();         workerGroup = new NioEventLoopGroup();         bootstrap = new ServerBootstrap();         bootstrap.group(bossGroup, workerGroup);          bootstrap.channel(NioServerSocketChannel.class);          bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {             @Override             protected void initChannel(SocketChannel ch) throws Exception {                 //todo: add more handler             }         });          doBind();     }      protected void doBind() {         if (closed) {             return;         }          bootstrap.bind(localPort).addListener(new ChannelFutureListener() {             @Override             public void operationComplete(ChannelFuture f) throws Exception {                 if (f.isSuccess()) {                     System.out.println("Started Tcp Server: " + localPort);                 } else {                     System.out.println("Started Tcp Server Failed: " + localPort);                      f.channel().eventLoop().schedule(() -> doBind(), 1, TimeUnit.SECONDS);                 }             }         });     } } 

我们把整个初始化分成了两个部分,第一部分是初始化相关 class,第二部分做真正的监听端口。

这里最特殊的地方就是在调用bind方法后,添加一个listener检查是否成功,如果失败的话,需要调用.channel().eventLoop().schedule()方法,创建一个任务,我这代码设置的是1秒后尝试重新连接。

另外考虑到 server 可以被人为关闭,所以还需要检查当前时候已经关闭。如果不检查的话,你的 server 可能就永远也关不掉了。

Client 端的处理

client 端启动流程差不多,但是需要加一个 handler 来处理连接断开。

public class TcpClient {      private volatile EventLoopGroup workerGroup;      private volatile Bootstrap bootstrap;      private volatile boolean closed = false;      private final String remoteHost;      private final int remotePort;      public TcpClient(String remoteHost, int remotePort) {         this.remoteHost = remoteHost;         this.remotePort = remotePort;     }      public void close() {         closed = true;         workerGroup.shutdownGracefully();         System.out.println("Stopped Tcp Client: " + getServerInfo());     }      public void init() {         closed = false;          workerGroup = new NioEventLoopGroup();         bootstrap = new Bootstrap();         bootstrap.group(workerGroup);         bootstrap.channel(NioSocketChannel.class);          bootstrap.handler(new ChannelInitializer<SocketChannel>() {             @Override             public void initChannel(SocketChannel ch) throws Exception {                 ChannelPipeline pipeline = ch.pipeline();                 pipeline.addFirst(new ChannelInboundHandlerAdapter() {                     @Override                     public void channelInactive(ChannelHandlerContext ctx) throws Exception {                         super.channelInactive(ctx);                         ctx.channel().eventLoop().schedule(() -> doConnect(), 1, TimeUnit.SECONDS);                     }                 });                  //todo: add more handler             }         });          doConnect();     }      private void doConnect() {         if (closed) {             return;         }          ChannelFuture future = bootstrap.connect(new InetSocketAddress(remoteHost, remotePort));          future.addListener(new ChannelFutureListener() {             public void operationComplete(ChannelFuture f) throws Exception {                 if (f.isSuccess()) {                     System.out.println("Started Tcp Client: " + getServerInfo());                 } else {                     System.out.println("Started Tcp Client Failed: " + getServerInfo());                     f.channel().eventLoop().schedule(() -> doConnect(), 1, TimeUnit.SECONDS);                 }             }         });     }      private String getServerInfo() {         return String.format("RemoteHost=%s RemotePort=%d",                 remotePort,                 remotePort);     } } 

可以看到,我们在channelInactive事件中,也创建了一个任务,在1秒后重新连接。

示例代码

大家可以自己跑跑看:

https://github.com/dozer47528/AutoReconnectNettyExample

本作品由 Dozer 创作,采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。

Netty 自动重连的更多相关文章

  1. netty系列之:自动重连

    目录 简介 使用netty建立连接 自动重连接的原理 模拟自动重连 总结 简介 我们在使用客户端和服务器端连接的过程中,可能会因为各种问题导致客户端和服务器的连接发生中断,遇到这种情况,一般情况下我们 ...

  2. Netty Client重连实现

    from:http://itindex.net/detail/54161-netty-client 当我们用Netty实现一个TCP client时,我们当然希望当连接断掉的时候Netty能够自动重连 ...

  3. Netty断线重连

    Netty断线重连 最近使用Netty开发一个中转服务,需要一直保持与Server端的连接,网络中断后需要可以自动重连,查询官网资料,实现方案很简单,核心思想是在channelUnregistered ...

  4. Netty Client 重连实现

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

  5. 如何实现Azure虚拟网络中点到站VPN的自动重连

     在Windows Azure早期版本中,用户要在某台Azure平台之外的机器与Azure平台内部的机器建立专用连接,可以借助Azure Connect这个功能.当前的Azure版本,已经没有Az ...

  6. 解读dbcp自动重连那些事---转载

    http://agapple.iteye.com/blog/791943 可以后另一篇做对比:http://agapple.iteye.com/blog/772507 同样的内容,不同的描述方式,不一 ...

  7. PERL DBI 自动重连问题

    [root@wx03 mojo]# cat relink.pl use Mojolicious::Lite; use JSON qw/encode_json decode_json/; use Enc ...

  8. NodeMCU之旅(二):断线自动重连,闪烁连接状态

    事件监听器 NodeMCU采用了事件响应的方式.也就是说,只需为事件设置一个回调函数,当事件发生时,回调函数就会被调用. 注册事件监听器 wif.sta.eventMonReg() 开始监听 wifi ...

  9. 【树莓派】树莓派下WiFi断线自动重连

    实现 WiFi 断线自动重连.原理是用 Python 监测网络是否断线,如果断线则重启网络服务. 1.Python 代码 autowifi.py,放在 /home/pi 目录下: #!/usr/bin ...

随机推荐

  1. JavaScript学习04 对象

    JavaScript学习04 对象 默认对象 日期对象Date, 格式:日期对象名称=new Date([日期参数]) 日期参数: 1.省略(最常用): 2.英文-数值格式:月 日,公元年 [时:分: ...

  2. 【即时通讯】XMPP调试与简单使用

    上篇讲了[即时通讯]即时通讯及XMPP概述及环境配置,接下来我们就要进行调试,看看是否可用! 在测试之前我们需要先事先保存一些东西,以便后面使用 —— 登录openfire后台 ——获取服务器名和端口 ...

  3. Java中的static的使用

    Java中的static使用之静态变量 神话丿小王子的博客主页 1.Java 中被static修饰的成员称为静态成员或类成员.它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享.且优先于对象 ...

  4. 如何为Swift进行宏定义

    这阵子一直在自学Swift, 因为之前iOS的开发一直用Objective-C, 所以习惯了C语言那种宏定义方式, Swift作为一款更加安全的语言, 放弃了C语言中的宏定义, 有效的防止预编译时代码 ...

  5. Log4jConfigListener cannot be found — context fails to start

    解决方案 Reticulogic's second suggestion is correct. However, in Eclipse Helios, the "Java EE Modul ...

  6. iOS之 Xcode7下 bitcode的工作流程及安全评估

    文章参考来自http://www.freebuf.com/articles/others-articles/89806.html 很多朋友在升级Xcode7以后原有正常运行的工程在Xcode7下编译会 ...

  7. Linux- Nginx简单的负载均衡(一)

    这里先进行简单的nginx负载,安装nginx这里就不多说了,我们情景假设在已经安装好了nginx上: 1)查询nginx中的upstrea负载均衡模块  默认是有安装的.进入nginx源码目录中 . ...

  8. DevExpress ASPxSplitter ClientSideEvents-PaneExpanded 时间用法

    在webform中的devexpress aspxsplitter中套用了jquery-easyui的 tabs id=tt <div id="tt" class=" ...

  9. 别再TM跟我说找不到满意的工作!

    上一篇老徐跟大家分享:如何判断自己在这家公司是否有成长? 今天只想跟大家说几个真是案例:别再TM总抱怨说找不到满意的工作 说明:如下案例,针对老徐当前的软件测试职业,其他职业可自己脑补--- / 1 ...

  10. 深入理解java垃圾回收机制

    深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...