Java Code Examples for org.apache.mina.core.buffer.IoBuffer#compact()

The following examples show how to use org.apache.mina.core.buffer.IoBuffer#compact() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TestNTGCodecPositive.java    From sailfish-core with Apache License 2.0 5 votes vote down vote up
private void decodeBytes(int[] ints) throws Exception{
	byte[] bytes = new byte[ints.length];
	for (int i =0; i<ints.length; i++)
	{
		bytes[i] = (byte) ints[i];
	}

       NTGCodec decodeCodec2 = new NTGCodec();
       decodeCodec2.init(serviceContext, null, DefaultMessageFactory.getFactory(), TestNTGHelper.getDictionary());
	ProtocolDecoderOutput decoderOutput2 = new MockProtocolDecoderOutput();

	IoBuffer toDecode = IoBuffer.wrap( new byte[0] );
	toDecode.setAutoExpand(true);
	toDecode.put(bytes);
	//IoBuffer.wrap( Arrays.copyOf(((IoBuffer)lastMessage).array(), ((IoBuffer)lastMessage).limit() ));
	toDecode.compact();
	toDecode.order(ByteOrder.LITTLE_ENDIAN);

	IoSession decodeSession2 = new DummySession();
	boolean decodableResult = decodeCodec2.decodable( decodeSession2, toDecode );
	Assert.assertTrue( "Test for decoding error.", decodableResult);
	decoderOutput2 = new MockProtocolDecoderOutput();

	boolean decodeResult = decodeCodec2.doDecode( decodeSession2, toDecode, decoderOutput2 );
	Assert.assertTrue( "Decoding error.", decodeResult );

       Assert.assertTrue("Message queue size must not less then 1.", ((AbstractProtocolDecoderOutput)decoderOutput2).getMessageQueue().size() >= 1);
	Object decodedMessage2 = ((AbstractProtocolDecoderOutput)decoderOutput2).getMessageQueue().element();

	Assert.assertTrue( "Object must be instance of IMessage.", decodedMessage2 instanceof IMessage);
	Assert.assertTrue( "Object must be instance of MapMessage.", decodedMessage2 instanceof MapMessage);
}
 
Example 2
Source File: TestNTGCodecNegative.java    From sailfish-core with Apache License 2.0 4 votes vote down vote up
/**
 * Negative test encode Heartbeat message with StartOfMessage=3 and decode it after
 */
@Test
public void testWrongMessage(){
       IMessage message = DefaultMessageFactory.getFactory().createMessage("Heartbeat", "NTG");
       IMessage messageHeader = DefaultMessageFactory.getFactory().createMessage("MessageHeader", "NTG");
	messageHeader.addField("StartOfMessage", 3);
	messageHeader.addField("MessageLength", 9);
	messageHeader.addField("MessageType", "2");
	message.addField("MessageHeader", messageHeader);
	try{
           IDictionaryStructure dictionary = TestNTGHelper.getDictionary();
           IMessageStructure msgStruct = dictionary.getMessages().get(message.getName());
		Assert.assertNotNull("Message structure is null.", msgStruct);
           NTGCodec encodeCodec = new NTGCodec();
		encodeCodec.init(serviceContext, null, DefaultMessageFactory.getFactory(), dictionary);
           ProtocolEncoderOutput output = new TestNTGHelper().new MockProtocolEncoderOutput();
 		encodeCodec.encode(new DummySession(), message, output);

		Queue<Object> msgQueue = ((AbstractProtocolEncoderOutput) output).getMessageQueue();

		Assert.assertNotNull("Message queue from AbstractProtocolEncoderOutput.", msgQueue);
           Assert.assertTrue("Message queue size must be equal 1.", msgQueue.size() == 1);

		Object lastMessage = msgQueue.element();

		if (lastMessage instanceof IoBuffer) {
               NTGCodec decodeCodec = new NTGCodec();
			decodeCodec.init(serviceContext, null, DefaultMessageFactory.getFactory(), dictionary);
			IoBuffer toDecode = IoBuffer.wrap( new byte[0] );
			toDecode.setAutoExpand(true);
			toDecode.put(((IoBuffer)lastMessage).array());
			toDecode.compact();
			toDecode.order(ByteOrder.LITTLE_ENDIAN);

			IoSession decodeSession = new DummySession();
			decodeCodec.decodable(decodeSession, toDecode);
			Assert.fail("Exception hasn't been thrown");
		}
	}catch(Exception e){
		Assert.assertEquals("Unexpected start of message: 3", e.getMessage());
	}

}
 
Example 3
Source File: TestNTGCodecPositive.java    From sailfish-core with Apache License 2.0 4 votes vote down vote up
private void testRoundTrip(IMessage message, IDictionaryStructure dictionary) {
	try
	{
           IMessageStructure msgStruct = dictionary.getMessages().get(message.getName());

		Assert.assertNotNull("Message structure is null.", msgStruct);

           NTGCodec encodeCodec = new NTGCodec();

		encodeCodec.init(serviceContext, null, DefaultMessageFactory.getFactory(), dictionary);

           ProtocolEncoderOutput output = new TestNTGHelper().new MockProtocolEncoderOutput();
			encodeCodec.encode(new DummySession(), message, output);

		Queue<Object> msgQueue = ((AbstractProtocolEncoderOutput) output).getMessageQueue();

		Assert.assertNotNull("Message queue from AbstractProtocolEncoderOutput.", msgQueue);
           Assert.assertTrue("Message queue size must be equal 1.", msgQueue.size() == 1);

		Object lastMessage = msgQueue.element();

		if (lastMessage instanceof IoBuffer) {
               NTGCodec decodeCodec = new NTGCodec();
			decodeCodec.init(serviceContext, null, DefaultMessageFactory.getFactory(), dictionary);
			AbstractProtocolDecoderOutput decoderOutput = new MockProtocolDecoderOutput();

			IoBuffer toDecode = IoBuffer.wrap( new byte[0] );
			toDecode.setAutoExpand(true);
			toDecode.put(((IoBuffer)lastMessage).array());
			//IoBuffer.wrap( Arrays.copyOf(((IoBuffer)lastMessage).array(), ((IoBuffer)lastMessage).limit() ));
			toDecode.compact();
			toDecode.order(ByteOrder.LITTLE_ENDIAN);

			IoSession decodeSession = new DummySession();
			boolean decodableResult = decodeCodec.decodable(decodeSession, toDecode);
			decoderOutput = new MockProtocolDecoderOutput();

			Assert.assertTrue("Test for decoding error.", decodableResult);

			boolean decodeResult = decodeCodec.doDecode(decodeSession, toDecode, decoderOutput);
			Assert.assertTrue("Decoding error.", decodeResult);

               Assert.assertTrue("Message queue size must not less then 1.", decoderOutput.getMessageQueue().size() >= 1);
			Object decodedMessage = decoderOutput.getMessageQueue().element();

			Assert.assertTrue( "Object must be instance of IMessage.", decodedMessage instanceof IMessage);
			Assert.assertTrue( "Object must be instance of MapMessage.", decodedMessage instanceof MapMessage);
               Assert.assertTrue("Messages must be equal. Original message:" + JsonMessageConverter.toJson(message, dictionary) + "; "
                       + "result message:" + JsonMessageConverter.toJson((IMessage)decodedMessage, dictionary),
                       message.compare((MapMessage) decodedMessage));
		}
	}
	catch (Exception e)
	{
	    logger.error(e.getMessage(), e);
		Assert.fail(ErrorUtil.formatException(e));
	}
}
 
Example 4
Source File: MinaProtocolDecoder.java    From jforgame with Apache License 2.0 4 votes vote down vote up
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	// 必须保证每一个数据包的字节缓存都和session绑定在一起,不然就读取不了上一次剩余的数据了
	CodecContext context = SessionManager.INSTANCE.getSessionAttr(session, MinaSessionProperties.CODEC_CONTEXT,
			CodecContext.class);
	if (context == null) {
		context = new CodecContext();
		session.setAttribute(MinaSessionProperties.CODEC_CONTEXT, context);
	}

	IoBuffer ioBuffer = context.getBuffer();
	ioBuffer.put(in);

	IMessageDecoder msgDecoder = SerializerHelper.getInstance().getDecoder();

	// 在循环里迭代,以处理数据粘包
	for (;;) {
		ioBuffer.flip();
		// 消息元信息常量3表示消息body前面的两个字段,一个short表示module,一个byte表示cmd,
		final int metaSize = 3;
		if (ioBuffer.remaining() < metaSize) {
			ioBuffer.compact();
			return;
		}
		// ----------------消息协议格式-------------------------
		// packetLength | moduleId | cmd  | body
		// int            short      byte byte[]
		int length = ioBuffer.getInt();
		// int packLen = length + metaSize;
		// 大于消息body长度,说明至少有一条完整的message消息
		if (ioBuffer.remaining() >= length) {
			short moduleId = ioBuffer.getShort();
			byte cmd = ioBuffer.get();
			int msgbodyLen = length - metaSize;
			byte[] body = new byte[msgbodyLen];
			ioBuffer.get(body);
			Message msg = msgDecoder.readMessage(moduleId, cmd, body);

			if (moduleId > 0) {
				out.write(msg);
			} else { // 属于组合包
				CombineMessage combineMessage = (CombineMessage) msg;
				List<Packet> packets = combineMessage.getPackets();
				for (Packet packet : packets) {
					// 依次拆包反序列化为具体的Message
					out.write(Packet.asMessage(packet));
				}
			}
			if (ioBuffer.remaining() == 0) {
				ioBuffer.clear();
				break;
			}
			ioBuffer.compact();
		} else {
			// 数据包不完整,继续等待数据到达
			ioBuffer.rewind();
			ioBuffer.compact();
			break;
		}
	}
}
 
Example 5
Source File: TPKTFilter.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
@Override
public void messageReceived ( final NextFilter nextFilter, final IoSession session, final Object message ) throws Exception
{
    if ( ! ( message instanceof IoBuffer ) )
    {
        nextFilter.messageReceived ( session, message );
        return;
    }

    final IoBuffer in = (IoBuffer)message;
    final IoBuffer sessionBuffer = getSessionBuffer ( session );

    // first add to the session buffer (may be optimized later)
    sessionBuffer.position ( sessionBuffer.limit () );
    sessionBuffer.put ( in );
    sessionBuffer.flip ();

    while ( sessionBuffer.remaining () >= 4 )
    {
        final int len = sessionBuffer.getUnsignedShort ( 2 );
        if ( sessionBuffer.remaining () < len )
        {
            logger.debug ( "Next packet requires {} bytes", new Object[] { len } );
            // not enough data for body
            return;
        }

        // convert
        final IoBuffer data = IoBuffer.allocate ( len - 4 );
        sessionBuffer.get (); // version
        sessionBuffer.get (); // reserved
        sessionBuffer.getUnsignedShort (); // length

        sessionBuffer.get ( data.array () );

        nextFilter.messageReceived ( session, data );

        logger.debug ( "{} bytes left in session buffer", sessionBuffer.remaining () );
    }

    if ( sessionBuffer.hasRemaining () )
    {
        sessionBuffer.compact ();
    }
    else
    {
        sessionBuffer.clear ().flip ();
    }
}
 
Example 6
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Decode all available objects in buffer.
 * 
 * @param conn
 *            RTMP connection
 * @param buffer
 *            IoBuffer of data to be decoded
 * @return a list of decoded objects, may be empty if nothing could be decoded
 */
public List<Object> decodeBuffer(RTMPConnection conn, IoBuffer buffer) {
    final int position = buffer.position();
    //if (log.isTraceEnabled()) {
    //log.trace("decodeBuffer: {}", Hex.encodeHexString(Arrays.copyOfRange(buffer.array(), position, buffer.limit())));
    //}
    // decoded results
    List<Object> result = null;
    if (conn != null) {
        //log.trace("Decoding for connection - session id: {}", conn.getSessionId());
        try {
            // instance list to hold results
            result = new LinkedList<>();
            // get the local decode state
            RTMPDecodeState state = conn.getDecoderState();
            //if (log.isTraceEnabled()) {
            //log.trace("RTMP decode state {}", state);
            //}
            if (!conn.getSessionId().equals(state.getSessionId())) {
                log.warn("Session decode overlap: {} != {}", conn.getSessionId(), state.getSessionId());
            }
            int remaining;
            while ((remaining = buffer.remaining()) > 0) {
                if (state.canStartDecoding(remaining)) {
                    //log.trace("Can start decoding");
                    state.startDecoding();
                } else {
                    log.trace("Cannot start decoding");
                    break;
                }
                final Object decodedObject = decode(conn, state, buffer);
                if (state.hasDecodedObject()) {
                    //log.trace("Has decoded object");
                    if (decodedObject != null) {
                        result.add(decodedObject);
                    }
                } else if (state.canContinueDecoding()) {
                    //log.trace("Can continue decoding");
                    continue;
                } else {
                    log.trace("Cannot continue decoding");
                    break;
                }
            }
        } catch (Exception ex) {
            log.warn("Failed to decodeBuffer: pos {}, limit {}, chunk size {}, buffer {}", position, buffer.limit(), conn.getState().getReadChunkSize(), Hex.encodeHexString(Arrays.copyOfRange(buffer.array(), position, buffer.limit())));
            // catch any non-handshake exception in the decoding; close the connection
            log.warn("Closing connection because decoding failed: {}", conn, ex);
            // clear the buffer to eliminate memory leaks when we can't parse protocol
            buffer.clear();
            // close connection because we can't parse data from it
            conn.close();
        } finally {
            //if (log.isTraceEnabled()) {
            //log.trace("decodeBuffer - post decode input buffer position: {} remaining: {}", buffer.position(), buffer.remaining());
            //}
            buffer.compact();
        }
    } else {
        log.error("Decoding buffer failed, no current connection!?");
    }
    return result;
}