##使用timer
bootstrap.setPipelineFactory( new ChannelPipelineFactory() { public ChannelPipeline getPipeline() { final ChannelPipeline p = Channels.pipeline(); // Reconnections p.addLast("reconnect", new ReconnectHandler( bootstrap, timer, reconnectDelay, TimeUnit.MILLISECONDS));
###timer
timer = HashedWheelTimerFactory.CreateDaemonHashedWheelTimer();
###HashedWheelTimerFactory
public class HashedWheelTimerFactory { public static ThreadFactory daemonThreadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread retVal = Executors.defaultThreadFactory().newThread(r); retVal.setDaemon(true); return retVal; } }; /** * Creates hashed wheel timer that uses daemon threads * * @return HashedWheelTimer */ public static HashedWheelTimer CreateDaemonHashedWheelTimer() { return new HashedWheelTimer(daemonThreadFactory); }}
###ReconnectHandler
public class ReconnectHandler extends SimpleChannelUpstreamHandler { final Bootstrap bootstrap; public final Timer timer; public long startTime = -1; public final AtomicLong delay; public final TimeUnit unit; public ReconnectHandler(ClientBootstrap bootstrap, Timer timer, AtomicLong delay, TimeUnit unit) { this.bootstrap = bootstrap; this.timer = timer; this.delay = delay; this.unit = unit; } public ReconnectHandler(ConnectionlessBootstrap bootstrap, Timer timer, AtomicLong delay, TimeUnit unit) { this.bootstrap = bootstrap; this.timer = timer; this.delay = delay; this.unit = unit; } InetSocketAddress getRemoteAddress() { Resolver resolver = (Resolver) bootstrap.getOption("resolver"); return resolver.resolve(); } @Override public void channelDisconnected(ChannelHandlerContext c, ChannelStateEvent e) throws Exception { // Go ahead and close. I don't know why Netty doesn't close disconnected // TCP sockets, but it seems not to. e.getChannel().close(); super.channelDisconnected(c, e); } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { try { timer.newTimeout(new TimerTask() { public void run(Timeout timeout) throws Exception { if (bootstrap instanceof ClientBootstrap) { ClientBootstrap b = (ClientBootstrap) bootstrap; b.setOption("remoteAddress", getRemoteAddress()); b.connect(); } else if (bootstrap instanceof ConnectionlessBootstrap) { ConnectionlessBootstrap b = (ConnectionlessBootstrap) bootstrap; b.setOption("remoteAddress", getRemoteAddress()); b.connect(); } } }, delay.get(), unit); } catch (java.lang.IllegalStateException ex) { // The timer must have been stopped. } super.channelClosed(ctx, e); } @Override public void channelConnected(ChannelHandlerContext c, ChannelStateEvent e) throws Exception { if (startTime < 0) { startTime = System.currentTimeMillis(); } super.channelConnected(c, e); } @Override public void exceptionCaught(ChannelHandlerContext c, ExceptionEvent e) { final Throwable cause = e.getCause(); if (cause instanceof ConnectException) { startTime = -1; } else if (cause instanceof ReadTimeoutException) { // The connection was OK but there was no traffic for the last period. } else { c.sendUpstream(e); } c.getChannel().close(); }}
##docs