关于netty一个比较常见?的问题

我的项目是做服务端的,需要和硬件设备建立一个长连接,心跳报文是客户端那边发,我这边不做处理。
我的项目目前遇到一个网上答案有限的问题:远程主机强制关闭一个连接。网上查的原因和解决方案大多是:由于远程客户端关闭连接,服务端代码不够健壮导致报错;需要增强代码健壮性。或者另一个解决方案是需要添加ctx.flush()或者ctx.close();但是ctx.flush()这个加了也会报错,而且我也不认为是远程主动关闭了链接,因为用调试助手测试远程的时候是没有问题的,所以我认为是我这边代码做了什么导致的远程关闭连接,查了一下发现如果在连接已经存在的条件下再次建立连接会导致远程出错,从而关闭连接,然后服务端读数据的时候报了远程主机强制关闭一个连接,我现在在从这边方面下手查,但是也不确定是不是这个原因,所以来问有没有大佬遇到过?
PS:项目需要通过每4秒检查读通道是否有数据来检查下发的召测是否有回传,每15分钟下发召测报文,30分钟没有读写则断开连接,这些我都是通过idleStateHandler解决的

idlestatehandler的配置:

@Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline()
                                    .addLast("decoder", new MyDecoder())
                                    .addLast("idleHandler",new IdleStateHandler(4,90,1860))
                                    .addLast("serverHandler",new ServerHandler());
                        }

@Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            if(e.state() == IdleState.READER_IDLE){
                if(...){
                    origin = origin + ClassUtil.postValidate(origin);
                    System.out.println("重新下发: "+origin);
                    ctx.writeAndFlush(ClassUtil.retMsg(origin));
                }
               System.out.println("read idle");
            }else if(e.state() == IdleState.WRITER_IDLE){
                System.out.println(new Date().toString()+": write idle");

                if(...){
                    origin = origin + ClassUtil.postValidate(origin);
                    System.out.println("下发: "+origin);
                    ctx.writeAndFlush(ClassUtil.retMsg(origin));
                }
            }else if(e.state() == IdleState.ALL_IDLE){
                System.out.println(equipCode+" all idle,disconnect...");
                ctx.disconnect();
            }
        }else {
            super.userEventTriggered(ctx, evt);
        }
        return;
    }

问题补充:有感觉可能和TCP长连接默认时长有关系,但是网上查的TCP默认时长是2小时,我的写操作是15分钟一次…

public void start() throws InterruptedException {
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup,workGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(9002))
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        private DefaultAttributeMap map = new DefaultAttributeMap();
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline()
                                    .addLast("decoder", new MyDecoder())
                                    .addLast("idleHandler",new IdleStateHandler(4,90,1860))
                                    .addLast("serverHandler",new ServerHandler());
                        }
                    });
            ChannelFuture future = b.bind().sync();//开启需要监听 的端口

            if (future.isSuccess()) {
                System.out.println("启动 netty 成功");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

基本上,所有的socket程序都可能遇到这个问题。就算是Tomcat/Undertow这种级别的应用。也是常见:远程主机强制关闭一个连接。 我觉得大多是客户端的问题,例如没有正常关闭程序,直接杀死进程。

但是我设置90秒一次下发召测就不会有这个问题