The Culture of Code
  1. Posts/

Implementing Automatic Reconnection for Netty Client

One of the first requirement of Netty ISO8588 client connector was the support for automatic reconnect.

One of the first receipts I came across was Thomas Termin’s one. He suggests adding a ChannelHandler which will schedule the calling of client’s connect() method once a Channel becomes inactive. Plus adding ChannelFutureListener which will re-create a bootstrap and re-connect if initial connection was failed.

Although this is a working solution, I had a feeling that something is not optimal. Namely, the new Bootstrap is being created on every connection attempt.

So, I created a FutureListener which should be registered once a Channel is closed.

Here is the ReconnectOnCloseListener code:

    public class ReconnectOnCloseListener implements ChannelFutureListener {

        private final Logger logger = getLogger(ReconnectOnCloseListener.class);

        private final Iso8583Client client;
        private final int reconnectInterval;
        private final AtomicBoolean disconnectRequested = new AtomicBoolean(false);
        private final ScheduledExecutorService executorService;

        public ReconnectOnCloseListener(Iso8583Client client, int reconnectInterval, ScheduledExecutorService executorService) {
            this.client = client;
            this.reconnectInterval = reconnectInterval;
            this.executorService = executorService;

        public void requestReconnect() {

        public void requestDisconnect() {

        public void operationComplete(ChannelFuture future) throws Exception {
            final Channel channel =;
            logger.debug("Client connection was closed to {}", channel.remoteAddress());

        public void scheduleReconnect() {
            if (!disconnectRequested.get()) {
                logger.trace("Failed to connect. Will try again in {} millis", reconnectInterval);
                        reconnectInterval, TimeUnit.MILLISECONDS);

To establish the connection I use the following code:

    final ChannelFuture connectFuture = bootstrap.connect();
    connectFuture.addListener(connFuture -> {
        if (!connectFuture.isSuccess()) {
        Channel channel =;"Client is connected to {}", channel.remoteAddress());
    connectFuture.sync();// if you need to connect synchronously

When you want to disconnect, you’ll need to disable automatic reconnection first:


The solution works fine so far (integration test).

Another option is to add a ChannelOutboundHandler which will handle disconnects.