/** * 着信したメッセージを処理し、セッションのデコーダを呼び出します。 着信バッファには複数のメッセージが含まれている可能性があるため、 デコーダが例外を投げるまでループする必要あり。 * * <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; } } } }
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { synchronized (decoder) { decoder.decode(session, in, out); } }