@Override
 public void init(PropertiesUtil properties) throws IOException {
   mSocketPool = SocketPool.getInstance();
   mPushQueue = PushQueue.getInstance();
   int HeartBeatExecutorThreadNum = properties.getHeartBeatExecutorThreadNum();
   mExecutor = Executors.newScheduledThreadPool(HeartBeatExecutorThreadNum);
   mHeartBeatInterval = properties.getHeartBeatInterval();
 }
  @Override
  public void run() {

    // Thread heartBeat = new Thread(new HeartBeatWorker(), "PUSH_SERVER_HEARTBEAT_WORKER");
    // heartBeat.setDaemon(true);
    // heartBeat.start();

    BiConsumer<String, Socket> consumer = new SocketConsumer();
    mSocketPool.forEach(
        consumer); // only first time iterate the socket already exist in the socketPool to add
                   // HeartBeat thread.
    // after that need to call addHeartBeat() add HeartBeat manually
    try {
      while (mServiceRunning) {
        ServerMessage msg = mPushQueue.deQueueMsg();

        if (msg == null) {
          // timeout return null object
          // currently do nothing
          LogUtil.logV("timeout return null object");
        } else {
          String UUID = msg.getMsg().getUUID();
          if (TextUtil.checkUUID(UUID)) {
            Socket socket = mSocketPool.getSocket(UUID);
            if (socket != null && socket.isConnected()) {
              OutputStream os;
              try {
                os = socket.getOutputStream();
                // os.write(Message.createHeatBeatMsg(UUID));
                Message send = msg.getMsg();
                send.setCommand(send.getCommand() | MessageState.CMD_PUSH_MSG_CLIENT);
                os.write(send.getData());
                os.flush();
                msg.setLastPushMsg(System.currentTimeMillis());
              } catch (IOException e) {
                LogUtil.logE("IOException", e);
              }
            } else {
              // when msg in PushQueue didn't have corresponding socket, no need to put msg back to
              // push queue, msg pool have this copy, wait for client check unread msg with service
              // just ignore this msg from push queue
              LogUtil.logI("msg in PushQueue didn't have corresponding socket");
            }
          }
        }
      }
    } catch (InterruptedException e) {
      LogUtil.logE("InterruptedException", e);
    }
  }