public void sendPacket(Packet packet) throws IOException {
    if (packet == null) {
      log.error("Packet is null,please check synchronize");
      return;
    }

    if (channelContext.getId() == null) {
      log.error("target socketChannelId is null!");
      return;
    }

    byte[] bytes = null;
    try {
      bytes = channelContext.getPacketHandler().onSend(packet, channelContext);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      return;
    }

    if (log.isDebugEnabled()) {
      log.debug("send:{}{}", Arrays.toString(bytes), packet);
    }

    if (bytes != null) {
      sendData(bytes, channelContext.getSocketChannel());

    } else {
      log.error("bytes is null");
    }
  }
  private static void checkConnection() {
    log.debug("start check connection...");

    BackendStarter.checkConnectable();

    Collection<ChannelContext> channelContexts =
        Nio.getInstance().getConnectionsByProtocol(BackendConf.getInstance().getProtocol());
    if (channelContexts == null) {
      return;
    }

    List<ChannelContext> removedList = new ArrayList<ChannelContext>();

    for (ChannelContext channelContext : channelContexts) {
      BackendServerConf backendServer = BackendExt.getBackendServer(channelContext);

      if (!backendServer.isConnectable() || channelContext.isNeedRemoved(interval)) {
        removedList.add(channelContext);
      }
    }

    for (ChannelContext channelContext : removedList) {
      Nio.getInstance().removeConnection(channelContext, "is not app_on and tcp_on");
    }
  }
  public void removeConnection(ChannelContext channelContext) {
    List<ChannelContext> set = mapOfProtocolAndChannelContexts.get(channelContext.getProtocol());

    if (set != null) {
      log.warn("remove channelContext:{}", channelContext.getId());
      set.remove(channelContext);
    }
  }
 public void addConnection(ChannelContext channelContext) {
   List<ChannelContext> set = mapOfProtocolAndChannelContexts.get(channelContext.getProtocol());
   if (set == null) {
     synchronized (mapOfProtocolAndChannelContexts) {
       if (set == null) {
         set = Collections.synchronizedList(new ArrayList<ChannelContext>());
         mapOfProtocolAndChannelContexts.put(channelContext.getProtocol(), set);
       }
     }
   }
   set.add(channelContext);
 }
  @Override
  public int handle(
      SocketChannel socketChannel, ChannelContext channelContext, String errorReason) {
    channelContext.getStatVo().getCountOfErrorPackage().incrementAndGet();
    log.error("[" + "] received error package, reason is " + errorReason);

    if (channelContext.getStatVo().getCountOfErrorPackage().get() >= MAX_COUNT) {
      channelContext.getStatVo().getCountOfErrorPackage().set(0);
      NioUtils.remove(channelContext, "received an error package");
    }
    return (int) channelContext.getStatVo().getCountOfErrorPackage().get();
  }
  private int send(SocketChannel socketChannel, ByteBuffer dataBuffer) throws IOException {
    int sendSize = socketChannel.write(dataBuffer);

    if (sendSize > 0) {
      channelContext.getStatVo().setCurrentSendTime(SystemTimer.currentTimeMillis());
      channelContext.getStatVo().setSentBytes(sendSize + channelContext.getStatVo().getSentBytes());
      StatVo.getAllSentBytes().addAndGet(sendSize);

      getProcessedMsgByteCount().addAndGet(sendSize);
    }

    return sendSize;
  }
 public void recordFailMsg(Packet packet, String failReason) {
   if (channelContext.isNeedRecordSendFailMsg()) {
     ConcurrentLinkedQueue<PacketVo> sendFailQueue = getSendFailQueue(true);
     if (sendFailQueue != null) {
       PacketVo packetPojo =
           PacketVo.createPacketVo(packet, SystemTimer.currentTimeMillis(), failReason);
       if (sendFailQueue.size() >= channelContext.getCountOfRecordSendFail()) {
         sendFailQueue.poll();
       }
       sendFailQueue.add(packetPojo);
     }
   }
 }
 @Override
 public void run() {
   Packet packet = null;
   try {
     while ((packet = getMsgQueue().poll()) != null) {
       sendPacket(packet);
     }
   } catch (IOException e) {
     recordFailMsg(packet, e.getMessage());
     channelContext
         .getWriteIOErrorHandler()
         .handle(
             channelContext.getSocketChannel(),
             e,
             channelContext,
             "IOException occured when writing");
   }
 }
 /** @param socketChannelId */
 public SendRunnable(ChannelContext channelContext) {
   this.channelContext = channelContext;
   super.setRunnableName(SendRunnable.class.getSimpleName() + " [" + channelContext.getId() + "]");
 }