почему переподключение клиента приводит к двойным соединениям с netty - PullRequest
0 голосов
/ 22 ноября 2018

Клиент переподключается к серверу, когда соединение с Netty закрыто.Но каждый раз, когда соединение теряется, клиент переподключается, используя два потока.Переподключение приводит к двойным соединениям.Как я могу решить проблему?

public class ImConnection {
    private static Logger logger = LoggerFactory.getLogger(ImConnection.class);
    private static Bootstrap b;
    private Channel channel;

    static {
        b = new Bootstrap();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        b.group(workerGroup);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.handler(new ConnectionInitializer());
    }

    public Channel connect() {
        doConnect(PropertyConstant.cfgcServerIP, PropertyConstant.cfgcServerPort);
        return this.channel;
    }
    private void doConnect(String host, int port) {
        try {
            ChannelFuture f = b.connect(host, port);
            f.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        final EventLoop loop = future.channel().eventLoop();
                        loop.schedule(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    connect(); // reconnect if fail
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }, 1L, TimeUnit.SECONDS);
                    } else {
                        logger.info("connected");
                    }
            }});
            channel = f.channel();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

инициализатор обработчика

public class ConnectionInitializer extends ChannelInitializer<Channel> {

    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ConnectionHandler());
    }
}

обработчик для повторного подключения при потере соединения

public class ConnectionHandler extends ChannelInboundHandlerAdapter {
    private ImConnection imConnection = new ImConnection();

    // get executed when connection drops
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("connection lost");
        final EventLoop eventLoop = ctx.channel().eventLoop();
        eventLoop.schedule(new Runnable() {
            @Override
            public void run() {
                imConnection.connect();
            }
        }, 1L, TimeUnit.SECONDS);
        super.channelInactive(ctx);
    }
}
...