Netty 自动重连
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
Netty 自动重连的更多相关文章
- netty系列之:自动重连
		
目录 简介 使用netty建立连接 自动重连接的原理 模拟自动重连 总结 简介 我们在使用客户端和服务器端连接的过程中,可能会因为各种问题导致客户端和服务器的连接发生中断,遇到这种情况,一般情况下我们 ...
 - Netty Client重连实现
		
from:http://itindex.net/detail/54161-netty-client 当我们用Netty实现一个TCP client时,我们当然希望当连接断掉的时候Netty能够自动重连 ...
 - Netty断线重连
		
Netty断线重连 最近使用Netty开发一个中转服务,需要一直保持与Server端的连接,网络中断后需要可以自动重连,查询官网资料,实现方案很简单,核心思想是在channelUnregistered ...
 - Netty Client 重连实现
		
当我们用Netty实现一个TCP client时,我们当然希望当连接断掉的时候Netty能够自动重连.Netty Client有两种情况下需要重连: Netty Client启动的时候需要重连 在程序 ...
 - 如何实现Azure虚拟网络中点到站VPN的自动重连
		
 在Windows Azure早期版本中,用户要在某台Azure平台之外的机器与Azure平台内部的机器建立专用连接,可以借助Azure Connect这个功能.当前的Azure版本,已经没有Az ...
 - 解读dbcp自动重连那些事---转载
		
http://agapple.iteye.com/blog/791943 可以后另一篇做对比:http://agapple.iteye.com/blog/772507 同样的内容,不同的描述方式,不一 ...
 - PERL DBI 自动重连问题
		
[root@wx03 mojo]# cat relink.pl use Mojolicious::Lite; use JSON qw/encode_json decode_json/; use Enc ...
 - NodeMCU之旅(二):断线自动重连,闪烁连接状态
		
事件监听器 NodeMCU采用了事件响应的方式.也就是说,只需为事件设置一个回调函数,当事件发生时,回调函数就会被调用. 注册事件监听器 wif.sta.eventMonReg() 开始监听 wifi ...
 - 【树莓派】树莓派下WiFi断线自动重连
		
实现 WiFi 断线自动重连.原理是用 Python 监测网络是否断线,如果断线则重启网络服务. 1.Python 代码 autowifi.py,放在 /home/pi 目录下: #!/usr/bin ...
 
随机推荐
- JavaBean的作用域
			
JavaBean的作用域 scope属性决定了JavaBean对象存在的范围. scope的可选值包括四种: page(默认值) request session application 这四个值对应的 ...
 - 操作系统开发系列—13.d.多进程 ●
			
进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态 ...
 - MySQL 常见的sql命令
			
注意事项: 1.sql 使用单引号来环绕文本值(大部分数据库系统也接受双引号).如果是数值,请不要使用引号. 一.数据库 1.创建数据库 CREATE DATABASE lesson ; 创建一个名字 ...
 - 我曾经的第一个OC程序
			
一. OC简介 C语言的基础上,增加了一层最小的面向对象语法 完全兼容C语言 可以在OC代码中混入C语言代码,甚至是C++代码 可以使用OC开发Mac OS X平台和iOS平台的应用程序 二. OC语 ...
 - iOS之 opencv3.0.framework
			
本文章的目的是从源代码包中编译出opencv2.framework供IOS开发使用. 基本上是按照http://docs.opencv.org/3.0-beta/doc/tutorials/intro ...
 - http - referer
			
以前对Http中Referer的认识不够透彻.最近理了理,记录一下. 1 Referer可以记录访问的来源,统计访问量,可以用来防盗链. 2 客户端用js不能篡改Referer,用一些插件什么的可以达 ...
 - Google Nexus5在linux下刷原生安卓 android6.0
			
之前将Nexus5刷成了MIUI系统,现在想体验一下安卓6.0,网上都是windows的教程,但如何在linux下刷机呢? 首先准备环境和工具: 1. 我的linux系统是lubuntu 15.10 ...
 - 给现有MVC 项目添加 WebAPI
			
1. 增加一个WebApi Controller, VS 会自动添加相关的引用,主要有System.Web.Http,System.Web.Http.WebHost,System.Net.Http 2 ...
 - flume架构初接触
			
flume优点 1.存储数据到任何中央数据库 2.进入数据速率大于写出速率,可以起到缓存作用,保证流的平稳 3.提供文本式路由 4.支持事务 5.可靠.容错.可伸缩.可定制.可管理 put的缺点 1. ...
 - 【Html5】Html5新特性Notification实现桌面消息推送(2016-05-25)
			
序:最近工作使用WorkTile,发现使用Chrome浏览器的时候如果有任务下发给我则会在桌面右下角提示(当前浏览器为最小化模式).感觉这个东西蛮有意思的,感觉可以给用户更好的体验,于是乎就查询了一下 ...