@Override public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { // Call finishDecode() first when a connection is closed. ProtocolDecoder decoder = getDecoder(session); ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter); try { decoder.finishDecode(session, decoderOut); } catch (Throwable t) { ProtocolDecoderException pde; if (t instanceof ProtocolDecoderException) { pde = (ProtocolDecoderException) t; } else { pde = new ProtocolDecoderException(t); } throw pde; } finally { // Dispose everything disposeCodec(session); decoderOut.flush(nextFilter, session); } // Call the next filter nextFilter.sessionClosed(session); }
/** * 着信したメッセージを処理し、セッションのデコーダを呼び出します。 着信バッファには複数のメッセージが含まれている可能性があるため、 デコーダが例外を投げるまでループする必要あり。 * * <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; } } } }
/** * Dispose the decoder, removing its instance from the session's attributes, and calling the * associated dispose method. */ private void disposeDecoder(IoSession session) { ProtocolDecoder decoder = (ProtocolDecoder) session.removeAttribute(DECODER); if (decoder == null) { return; } try { decoder.dispose(session); } catch (Throwable t) { LOGGER.warn("Failed to dispose: " + decoder.getClass().getName() + " (" + decoder + ')'); } }
public void dispose(IoSession session) throws Exception { synchronized (decoder) { decoder.dispose(session); } }
public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception { synchronized (decoder) { decoder.finishDecode(session, out); } }
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { synchronized (decoder) { decoder.decode(session, in, out); } }