title: can't detect server-side offline in netty
body: <p>my question just like this:
  "specifically i am interested in the case where the other end of the channel dies unexpectedly (eg the process gets killed). it seems that netty does not reliably fire a channel closed/disconnect event, sometimes it does and sometimes it does not. it also does not necessarily throw a SocketException for connection reset."</p>
  
  <p>but my software need to keep connected at any possible conditon,unless device shutdown or net wire break.</p>
  
  <p>i connect a tcp device with netty.
  device as tcp server-side,tcp client-side write by netty.
  i use netty tcp-client to receive continus data from device.
  this connect is a long connect ,never be colsed on usual.
  now,how i could detect the device is offline with unexcept conditions,like shutdown by poweroff button or net wire has broken.
  the heartbeat of netty can not work well .</p>
  
  <pre><code>cpLine.addLast("idleStateHandler", new IdleStateHandler(new HashedWheelTimer(), 5, 0, 0));
  cpLine.addLast("heartbeatHandler", new HeartbeatHandler());.
  </code></pre>
  
  <p>,</p>
  
  <pre><code>public void init()
      {
          factory = new NioClientSocketChannelFactory(MainFrame.THREAD_POOL,
                  MainFrame.THREAD_POOL);
          bootstrap = new ClientBootstrap(factory);
          bootstrap.setPipelineFactory(new ChannelPipelineFactory()
          {
              public ChannelPipeline getPipeline() throws Exception
              {
                  ChannelPipeline cpLine = Channels.pipeline();
                  cpLine.addLast("idleStateHandler", new IdleStateHandler(new HashedWheelTimer(), 5, 0, 0));
                  cpLine.addLast("heartbeatHandler", new HeartbeatHandler());
                  for (ChannelHandler handler : handlerList)
                  {
                      cpLine.addLast(handler.toString(), handler);
                  }
                  return cpLine;
              }
          });
  
          bootstrap.setOption("child.tcpNoDelay", true);
          bootstrap.setOption("child.keepAlive", true);
          bootstrap.setOption("writeBufferHighWaterMark", 100*1024*1024);
          connect();
          Log.debug("TCPClient 初始化完成！");
      }
  </code></pre>
  
  <p>i still can't detect device-side offline.
  when i get the idlestatus ,i can't just simply close the channel in HeartbeatHandler.because get readidlestatus not means the device has shutdown,it could be has no data to trasfer.</p>
  
  <p>this is the HeartbeatHandler:</p>
  
  <pre><code>public class HeartbeatHandler extends IdleStateAwareChannelHandler {
  
      Logger log=LogManager.getLogger(HeartbeatHandler.class);
      @Override
      public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) {
          if (e.getState() == IdleState.READER_IDLE) {
              log.info("Reader idle, closing channel");
              //e.getChannel().close();
              e.getChannel().write("heartbeat-reader_idle");
          }
          else if (e.getState() == IdleState.WRITER_IDLE) {
              log.info("Writer idle, sending heartbeat");
              e.getChannel().write("heartbeat-writer_idle");
          }
          else if (e.getState() == IdleState.ALL_IDLE) {
              log.info("All idle, sending heartbeat");
              e.getChannel().write("heartbeat-all_idle");
          }
      }
  }
  </code></pre>