@Override public void fire() { IoSession session = getSession(); NextFilter nextFilter = getNextFilter(); IoEventType type = getType(); if (DEBUG) { LOGGER.debug("Firing a {} event for session {}", type, session.getId()); } switch (type) { case MESSAGE_RECEIVED: Object parameter = getParameter(); nextFilter.messageReceived(session, parameter); break; case MESSAGE_SENT: WriteRequest writeRequest = (WriteRequest) getParameter(); nextFilter.messageSent(session, writeRequest); break; case WRITE: writeRequest = (WriteRequest) getParameter(); nextFilter.filterWrite(session, writeRequest); break; case CLOSE: nextFilter.filterClose(session); break; case EXCEPTION_CAUGHT: Throwable throwable = (Throwable) getParameter(); nextFilter.exceptionCaught(session, throwable); break; case SESSION_IDLE: nextFilter.sessionIdle(session, (IdleStatus) getParameter()); break; case SESSION_OPENED: nextFilter.sessionOpened(session); break; case SESSION_CREATED: nextFilter.sessionCreated(session); break; case SESSION_CLOSED: nextFilter.sessionClosed(session); break; default: throw new IllegalArgumentException("Unknown event type: " + type); } if (DEBUG) { LOGGER.debug("Event {} has been fired for session {}", type, session.getId()); } }
/** * Force the NioSession to be released and cleaned up. * * @param session */ private void forceClose(final IoSession session) { log.warn("Force close - session: {}", session.getId()); if (session.containsAttribute("FORCED_CLOSE")) { log.info("Close already forced on this session: {}", session.getId()); } else { // set flag session.setAttribute("FORCED_CLOSE", Boolean.TRUE); session.suspendRead(); cleanSession(session, true); } }
private static String getSessionInfo(IoSession session) { if (session != null) { return "[" + (session.getAttribute("ID") == null ? String.valueOf(session.getId()) : session.getAttribute("ID")) + "]" + "[" + session.getId() + "] => " + session.getRemoteAddress(); } return "[NULL] => NULL"; }
/** {@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); } }
/** Calls {@link IoServiceListener#sessionDestroyed(IoSession)} for all registered listeners. */ public void fireSessionDestroyed(IoSession session) { // Try to remove the remaining empty session set after removal. if (managedSessions.remove(Long.valueOf(session.getId())) == null) { return; } // Fire session events. session.getFilterChain().fireSessionClosed(); // Fire listener events. try { for (IoServiceListener l : listeners) { try { l.sessionDestroyed(session); } catch (Throwable e) { ExceptionMonitor.getInstance().exceptionCaught(e); } } } finally { // Fire a virtual service deactivation event for the last session of the connector. if (session.getService() instanceof IoConnector) { boolean lastSession = false; synchronized (managedSessions) { lastSession = managedSessions.isEmpty(); } if (lastSession) { fireServiceDeactivated(); } } } }
/** * 着信したメッセージを処理し、セッションのデコーダを呼び出します。 着信バッファには複数のメッセージが含まれている可能性があるため、 デコーダが例外を投げるまでループする必要あり。 * * <p>while ( buffer not empty ) try decode ( buffer ) catch break; */ @Override public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { LOGGER.debug("Processing a MESSAGE_RECEIVED for session {}", session.getId()); if (!(message instanceof IoBuffer)) { nextFilter.messageReceived(session, message); return; } IoBuffer in = (IoBuffer) message; ProtocolDecoder decoder = getDecoder(session); ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter); // Loop until we don't have anymore byte in the buffer, // or until the decoder throws an unrecoverable exception or // can't decoder a message, because there are not enough // data in the buffer while (in.hasRemaining()) { int oldPos = in.position(); try { synchronized (decoderOut) { // Call the decoder with the read bytes decoder.decode(session, in, decoderOut); } // Finish decoding if no exception was thrown. decoderOut.flush(nextFilter, session); } catch (Throwable t) { ProtocolDecoderException pde; if (t instanceof ProtocolDecoderException) { pde = (ProtocolDecoderException) t; } else { pde = new ProtocolDecoderException(t); } if (pde.getHexdump() == null) { // Generate a message hex dump int curPos = in.position(); in.position(oldPos); pde.setHexdump(in.getHexDump()); in.position(curPos); } // Fire the exceptionCaught event. decoderOut.flush(nextFilter, session); nextFilter.exceptionCaught(session, pde); // Retry only if the type of the caught exception is // recoverable and the buffer position has changed. // We check buffer position additionally to prevent an // infinite loop. if (!(t instanceof RecoverableProtocolDecoderException) || (in.position() == oldPos)) { break; } } } }
/** {@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); }
/** * Close and clean-up the IoSession. * * @param session * @param immediately close without waiting for the write queue to flush */ @SuppressWarnings("deprecation") private void cleanSession(final IoSession session, boolean immediately) { // clean up final String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID); if (log.isDebugEnabled()) { log.debug("Forcing close on session: {} id: {}", session.getId(), sessionId); log.debug("Session closing: {}", session.isClosing()); } // get the write request queue final WriteRequestQueue writeQueue = session.getWriteRequestQueue(); if (writeQueue != null && !writeQueue.isEmpty(session)) { log.debug("Clearing write queue"); try { writeQueue.clear(session); } catch (Exception ex) { // clear seems to cause a write to closed session ex in some cases log.warn("Exception clearing write queue for {}", sessionId, ex); } } // force close the session final CloseFuture future = immediately ? session.close(false) : session.close(true); IoFutureListener<CloseFuture> listener = new IoFutureListener<CloseFuture>() { @SuppressWarnings({"unchecked", "rawtypes"}) public void operationComplete(CloseFuture future) { // now connection should be closed log.debug("Close operation completed {}: {}", sessionId, future.isClosed()); future.removeListener(this); for (Object key : session.getAttributeKeys()) { Object obj = session.getAttribute(key); log.debug("{}: {}", key, obj); if (obj != null) { if (log.isTraceEnabled()) { log.trace("Attribute: {}", obj.getClass().getName()); } if (obj instanceof IoProcessor) { log.debug("Flushing session in processor"); ((IoProcessor) obj).flush(session); log.debug("Removing session from processor"); ((IoProcessor) obj).remove(session); } else if (obj instanceof IoBuffer) { log.debug("Clearing session buffer"); ((IoBuffer) obj).clear(); ((IoBuffer) obj).free(); } } } } }; future.addListener(listener); }
/** {@inheritDoc} */ @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { log.debug("Filter chain: {}", session.getFilterChain()); String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID); if (log.isDebugEnabled()) { log.warn("Exception caught on session: {} id: {}", session.getId(), sessionId, cause); } if (cause instanceof IOException) { // Mina states that the connection will be automatically closed when an IOException is caught log.debug("IOException caught on {}", sessionId); } else { log.debug("Non-IOException caught on {}", sessionId); forceClose(session); } }
/** {@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); } } }
/** Calls {@link IoServiceListener#sessionCreated(IoSession)} for all registered listeners. */ public void fireSessionCreated(IoSession session) { boolean firstSession = false; if (session.getService() instanceof IoConnector) { synchronized (managedSessions) { firstSession = managedSessions.isEmpty(); } } // If already registered, ignore. if (managedSessions.putIfAbsent(Long.valueOf(session.getId()), session) != null) { return; } // If the first connector session, fire a virtual service activation event. if (firstSession) { fireServiceActivated(); } // Fire session events. session.getFilterChain().fireSessionCreated(); session.getFilterChain().fireSessionOpened(); int managedSessionCount = managedSessions.size(); if (managedSessionCount > largestManagedSessionCount) { largestManagedSessionCount = managedSessionCount; } cumulativeManagedSessionCount++; // Fire listener events. for (IoServiceListener l : listeners) { try { l.sessionCreated(session); } catch (Throwable e) { ExceptionMonitor.getInstance().exceptionCaught(e); } } }
@Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println(" Client " + session.getId() + "|IDLE " + session.getIdleCount(status)); }
public GameClient(IoSession session) { this.session = session; logger = (Logger) LoggerFactory.getLogger("gsession" + session.getId()); logger.info("has been created"); }
@Override public void sessionCreated(IoSession session) throws Exception { System.out.println(session.getId() + ":sessionCreated"); super.sessionCreated(session); }