转载自:http://colobu.com/2015/08/14/netty-tcp-client-with-reconnect-handling/
当使用Netty实现一个TCP client时,希望当连接断掉的时候Netty能够自动重连。下面来实现这个需求。
实现ChannelFutureListener 用来启动时监测是否连接成功,不成功的话重试:
当使用Netty实现一个TCP client时,希望当连接断掉的时候Netty能够自动重连。下面来实现这个需求。
实现ChannelFutureListener 用来启动时监测是否连接成功,不成功的话重试:
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 负责重连: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监测连接是否断掉,断掉的话也要重连:public class MyInboundHandler extends ChannelInboundHandlerAdapter {
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);
}
}