/** {@inheritDoc} */
 @Override
 public void sessionOpened(IoSession session) throws Exception {
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   log.debug("Session opened: {} id: {}", session.getId(), sessionId);
   RTMPConnManager connManager = (RTMPConnManager) RTMPConnManager.getInstance();
   session.setAttribute(
       RTMPConnection.RTMP_CONN_MANAGER,
       new WeakReference<IConnectionManager<RTMPConnection>>(connManager));
   RTMPMinaConnection conn = (RTMPMinaConnection) connManager.getConnectionBySessionId(sessionId);
   handler.connectionOpened(conn);
 }
 /** {@inheritDoc} */
 @Override
 public void sessionClosed(IoSession session) throws Exception {
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   log.debug("Session closed: {} id: {}", session.getId(), sessionId);
   if (log.isTraceEnabled()) {
     log.trace("Session attributes: {}", session.getAttributeKeys());
   }
   if (sessionId != null) {
     RTMPMinaConnection conn =
         (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId);
     if (conn != null) {
       // fire-off closed event
       handler.connectionClosed(conn);
       // clear any session attributes we may have previously set
       // TODO: verify this cleanup code is necessary. The session is over and will be garbage
       // collected surely?
       if (session.containsAttribute(RTMPConnection.RTMP_HANDSHAKE)) {
         session.removeAttribute(RTMPConnection.RTMP_HANDSHAKE);
       }
       if (session.containsAttribute(RTMPConnection.RTMPE_CIPHER_IN)) {
         session.removeAttribute(RTMPConnection.RTMPE_CIPHER_IN);
         session.removeAttribute(RTMPConnection.RTMPE_CIPHER_OUT);
       }
     } else {
       log.warn("Connection was not found for {}", sessionId);
     }
     cleanSession(session, false);
   } else {
     log.debug("Connections session id was null in session, may already be closed");
   }
 }
 /** {@inheritDoc} */
 @Override
 public void messageReceived(IoSession session, Object message) throws Exception {
   if (log.isTraceEnabled()) {
     log.trace("messageReceived session: {} message: {}", session, message);
     log.trace("Filter chain: {}", session.getFilterChain());
   }
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   if (log.isTraceEnabled()) {
     log.trace("Message received on session: {} id: {}", session.getId(), sessionId);
   }
   RTMPMinaConnection conn =
       (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId);
   if (conn != null) {
     if (message != null) {
       if (message instanceof Packet) {
         byte state = conn.getStateCode();
         // checking the state before allowing a task to be created will hopefully prevent rejected
         // task exceptions
         if (state != RTMP.STATE_DISCONNECTING && state != RTMP.STATE_DISCONNECTED) {
           conn.handleMessageReceived((Packet) message);
         } else {
           log.info(
               "Ignoring received message on {} due to state: {}", sessionId, RTMP.states[state]);
         }
       }
     }
   } else {
     log.warn("Connection was not found for {}, force closing", sessionId);
     forceClose(session);
   }
 }
 /** {@inheritDoc} */
 public void connectionClosed(RTMPConnection conn) {
   log.debug("connectionClosed: {}", conn.getSessionId());
   if (conn.getStateCode() != RTMP.STATE_DISCONNECTED) {
     // inform any callbacks for pending calls that the connection is
     // closed
     conn.sendPendingServiceCallsCloseError();
     // close the connection
     if (conn.getStateCode() != RTMP.STATE_DISCONNECTING) {
       conn.close();
     }
     // set as disconnected
     conn.setStateCode(RTMP.STATE_DISCONNECTED);
     // remove from the manager
     RTMPConnManager.getInstance().removeConnection(conn.getSessionId());
   }
   log.trace("connectionClosed: {}", conn);
 }
 /** {@inheritDoc} */
 @Override
 public void messageSent(IoSession session, Object message) throws Exception {
   log.trace("messageSent session: {} message: {}", session, message);
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   if (log.isTraceEnabled()) {
     log.trace("Message sent on session: {} id: {}", session.getId(), sessionId);
   }
   if (sessionId != null) {
     RTMPMinaConnection conn =
         (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId);
     if (conn != null) {
       final byte state = conn.getStateCode();
       switch (state) {
         case RTMP.STATE_CONNECTED:
           if (message instanceof Packet) {
             handler.messageSent(conn, (Packet) message);
           } else if (log.isDebugEnabled()) {
             log.debug(
                 "Message was not of Packet type; its type: {}",
                 message != null ? message.getClass().getName() : "null");
           }
           break;
         case RTMP.STATE_CONNECT:
         case RTMP.STATE_HANDSHAKE:
           if (log.isTraceEnabled()) {
             log.trace("messageSent: {}", Hex.encodeHexString(((IoBuffer) message).array()));
           }
           break;
         case RTMP.STATE_DISCONNECTING:
         case RTMP.STATE_DISCONNECTED:
         default:
       }
     } else {
       log.warn(
           "Destination connection was null, it is already disposed. Session id: {}", sessionId);
     }
   }
 }
 protected RTMPMinaConnection createRTMPMinaConnection() {
   return (RTMPMinaConnection)
       RTMPConnManager.getInstance().createConnection(RTMPMinaConnection.class);
 }