Как переподключиться к серверу после того, как сервер перестал обслуживать запрос в Netty IO - PullRequest
0 голосов
/ 11 июня 2018

Мой netty IO клиент должен продолжать пытаться подключиться к серверу всякий раз, когда сервер перезапускается или разрывается существующее соединение.Чтобы реализовать это, мой клиент создает новый поток для установления нового соединения всякий раз, когда вызывается метод обратного вызова ChannelInActive моего ChannelInboundHandlerAdapter.Но мой клиент выдает следующую ошибку при установлении нового соединения.

Исключение в потоке "main" io.netty.channel.AbstractChannel $ AnnotatedConnectException: в соединении отказано: никакой дополнительной информации: /127.0.0.1:8888 в sun.nio.ch.SocketChannelImpl.checkConnect (собственный метод) в sun.nio.ch.SocketChannelImpl.finishConnect (неизвестный источник) в io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect (NioSocketChan.5)на io.netty.channel.nio.AbstractNioChannel $ AbstractNioUnsafe.finishConnect (AbstractNioChannel.java:340) на io.netty.channel.nio.NioEventLoop.processSelectedKey (NioEventLoop.java:633) на ioventty.ioEnel.chan.Свойствоnetty.util.concurrent.SingleThreadEventExecutor $ 5.run (SingleThreadEventExecutor.java:886) в io.netty.util.concurrent.FastThreadLocalRunnable.run (FastThreadLocalRunnable.java:30) на java.lang.Thread.run (неизвестный источник). Причина: java.net.ConnectException: Отказ в соединении: нет дополнительной информации ... еще 11

Ниже приведены строки выполнения моей цепочки соединений.

EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group);
bootstrap.channel(NioSocketChannel.class).handler(new 
ChannelInitializer<SocketChannel>() {

        protected void initChannel(SocketChannel socketChannel) throws 
Exception {
            socketChannel.pipeline().addLast(new 
LengthFieldBasedFrameDecoder(64 * 1024, 0, 2));
            socketChannel.pipeline().addLast(ClientHandler);
        }

    });
    bootstrap.option(ChannelOption.SO_REUSEADDR,true);
    ChannelFuture channelFuture=null;
try 
{
    channelFuture = bootstrap.connect(new InetSocketAddress(IP, 
port)).sync();      
    channelFuture.awaitUninterruptibly();
    channelFuture.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture channelFuture)
         {
        try
        {
            if (channelFuture.isSuccess()) {
            if(connectfuture!=null) connectfuture.cancel(true);log.debug("Cancelled connection thread scheduler");

        } else {
            channelFuture.cause().printStackTrace();
        connectfuture=channelFuture.channel().eventLoop().scheduleAtFixedRate(new ClientConnectorThread(ClientHandler,IP,port) , 5,30, TimeUnit.SECONDS);
        }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        }
        } );

}

catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

1 Ответ

0 голосов
/ 11 июня 2018

Когда я хочу реализовать логику повторного подключения, я делаю это следующим образом

Добавление двух обработчиков для конвейера для захвата состояния простоя

pipeline.addLast(new ReadTimeoutHandler(readTimeout, TimeUnit.SECONDS));
pipeline.addLast("ReconnectionHandler", new ReconnectionHandler());

В ReconnectionHandler захват пользовательского событиясрабатывает ReadTimeoutHandler, отключите канал и попробуйте восстановить

public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
    if (evt instanceof IdleStateEvent) {
        IdleStateEvent e = (IdleStateEvent) evt;
        if (e.state() == IdleState.READER_IDLE) {
            ctx.close();
        }
    } else {
        ctx.fireUserEventTriggered(evt);
    }
}

public void channelUnregistered(final ChannelHandlerContext ctx) throws Exception {
    final EventLoopGroup eventLoopGroup = ctx.channel().eventLoop().parent();
    eventLoopGroup.schedule(() -> {
        bootstrap.connect()
    }, reconnectDelay, TimeUnit.SECONDS);
    ctx.fireChannelUnregistered();
}
...