/**
   * a message was received from the server. Here we dispatch the message to the client's thread
   * pool to minimize the time it takes to process other messages.
   *
   * @param ctx The channel the message was received from
   * @param msg The message
   */
  @Override
  protected void channelRead0(ChannelHandlerContext ctx, eye.Comm.Request msg) throws Exception {
    for (String id : listeners.keySet()) {
      CommListener cl = listeners.get(id);

      // TODO this may need to be delegated to a thread pool to allow
      // async processing of replies

      logger.info("inside channel read() got message from server :" + msg.getHeader().getTag());
      cl.onMessage(msg);
    }
  }
  /**
   * Notification registration. Classes/Applications receiving information will register their
   * interest in receiving content.
   *
   * <p>Note: Notification is serial, FIFO like. If multiple listeners are present, the data
   * (message) is passed to the listener as a mutable object.
   *
   * @param listener
   */
  public void addListener(CommListener listener) {
    if (listener == null) return;

    listeners.putIfAbsent(listener.getListenerID(), listener);
  }