/// <inheritdoc/> public override void SessionClosed(INextFilter nextFilter, IoSession session) { // Call finishDecode() first when a connection is closed. IProtocolDecoder decoder = _factory.GetDecoder(session); IProtocolDecoderOutput decoderOut = GetDecoderOut(session, nextFilter); try { decoder.FinishDecode(session, decoderOut); } catch (Exception ex) { ProtocolDecoderException pde = ex as ProtocolDecoderException; if (pde == null) { pde = new ProtocolDecoderException(null, ex); } throw pde; } finally { // Dispose everything DisposeCodec(session); decoderOut.Flush(nextFilter, session); } // Call the next filter nextFilter.SessionClosed(session); }
/// <inheritdoc/> public override void MessageReceived(INextFilter nextFilter, IoSession session, Object message) { //if (log.IsDebugEnabled) // log.DebugFormat("Processing a MESSAGE_RECEIVED for session {0}", session.Id); IoBuffer input = message as IoBuffer; if (input == null) { nextFilter.MessageReceived(session, message); return; } IProtocolDecoder decoder = _factory.GetDecoder(session); IProtocolDecoderOutput decoderOutput = 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 (input.HasRemaining) { Int32 oldPos = input.Position; try { // TODO may not need lock on UDP lock (session) { // Call the decoder with the read bytes decoder.Decode(session, input, decoderOutput); } // Finish decoding if no exception was thrown. decoderOutput.Flush(nextFilter, session); } catch (Exception ex) { ProtocolDecoderException pde = ex as ProtocolDecoderException; if (pde == null) { pde = new ProtocolDecoderException(null, ex); } if (pde.Hexdump == null) { // Generate a message hex dump Int32 curPos = input.Position; input.Position = oldPos; pde.Hexdump = input.GetHexDump(); input.Position = curPos; } decoderOutput.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 (!(ex is RecoverableProtocolDecoderException) || input.Position == oldPos) { break; } } } }