All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.netty.protocol.nrpc.codec.RpcDecoder Maven / Gradle / Ivy

The newest version!
package com.github.netty.protocol.nrpc.codec;

import com.github.netty.protocol.nrpc.RpcPacket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.ReferenceCountUtil;

import static com.github.netty.core.util.IOUtil.BYTE_LENGTH;
import static com.github.netty.core.util.IOUtil.INT_LENGTH;
import static com.github.netty.protocol.nrpc.RpcPacket.RequestPacket;
import static com.github.netty.protocol.nrpc.RpcPacket.ResponsePacket;
import static com.github.netty.protocol.nrpc.codec.RpcEncoder.PROTOCOL_HEADER;
import static com.github.netty.protocol.nrpc.codec.RpcEncoder.RPC_CHARSET;

/**
 * RPC decoder
 * 

*

* Request Packet (note: 1 = request type) * -+------8B--------+--1B--+--1B--+------4B------+-----4B-----+-----4B-----+------1B--------+-----length-----+------1B-------+---length----+-----4B------+-------length-------------+ * | header/version | type | ACK | total length | Request ID| timeout/ms | service length | service name | method length | method name | data length | data | * | NRPC/010 | 1 | 1 | 55 | 1 | 1000 | 8 | "/sys/user" | 7 | getUser | 24 | {"age":10,"name":"wang"} | * -+----------------+------+------+--------------+------------+------------+----------------+----------------+---------------+-------------+-------------+--------------------------+ *

*

* Response Packet (note: 2 = response type) * -+------8B--------+--1B--+--1B--+------4B------+-----4B-----+---2B---+--------1B------+--length--+---1B---+-----4B------+----------length----------+ * | header/version | type | ACK | total length | Request ID | status | message length | message | encode | data length | data | * | NRPC/010 | 2 | 0 | 35 | 1 | 200 | 2 | ok | 1 | 24 | {"age":10,"name":"wang"} | * -+----------------+------+------+--------------+------------+--------+----------------+----------+--------+-------------+--------------------------+ * * @author wangzihao */ public class RpcDecoder extends LengthFieldBasedFrameDecoder { private static final byte[] EMPTY = {}; private static final int LENGTH_FIELD_OFFSET = PROTOCOL_HEADER.length + BYTE_LENGTH + BYTE_LENGTH; public RpcDecoder() { this(10 * 1024 * 1024); } public RpcDecoder(int maxLength) { super(maxLength, // header | type | ACK LENGTH_FIELD_OFFSET, INT_LENGTH, 0, 0, true); } @Override protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { ByteBuf msg = (ByteBuf) super.decode(ctx, buffer); if (msg == null) { return null; } try { return decodeToPojo(msg); } finally { if (msg.refCnt() > 0) { ReferenceCountUtil.safeRelease(msg); } } } /** * Resolve to the entity class * * @param msg msg * @return */ protected Object decodeToPojo(ByteBuf msg) { //Skip protocol header msg.skipBytes(PROTOCOL_HEADER.length); byte rpcType = msg.readByte(); byte ack = msg.readByte(); //read total length long totalLength = msg.readUnsignedInt(); long totalPacketLength = totalLength + LENGTH_FIELD_OFFSET; switch (rpcType) { case RpcPacket.TYPE_CLIENT_REQUEST: { RequestPacket packet = RequestPacket.newInstance(); packet.setPacketLength(totalPacketLength); //Ack packet.setAck(ack); //Request ID packet.setRequestId(msg.readInt()); //Request Timeout packet.setTimeout(msg.readInt()); //Request service name packet.setRequestMappingName(msg.readCharSequence(msg.readUnsignedByte(), RPC_CHARSET).toString()); //Request service version packet.setVersion(msg.readCharSequence(msg.readUnsignedByte(), RPC_CHARSET).toString()); //Request method packet.setMethodName(msg.readCharSequence(msg.readUnsignedByte(), RPC_CHARSET).toString()); //Request data long dataLength = msg.readUnsignedInt(); if (dataLength > 0) { packet.setData(new byte[(int) dataLength]); msg.readBytes(packet.getData()); } else { packet.setData(EMPTY); } return packet; } case RpcPacket.TYPE_RESPONSE_CHUNK_ACK: case RpcPacket.TYPE_RESPONSE_CHUNK: case RpcPacket.TYPE_RESPONSE_LAST: { ResponsePacket packet = ResponsePacket.newInstance(rpcType); packet.setPacketLength(totalPacketLength); //Ack packet.setAck(ack); //Request ID packet.setRequestId(msg.readInt()); //Response status packet.setStatus(msg.readUnsignedShort()); //Response encode packet.setEncode(DataCodec.Encode.indexOf(msg.readUnsignedByte())); //Response information packet.setMessage(msg.readCharSequence(msg.readUnsignedByte(), RPC_CHARSET).toString()); //Request data long dataLength = msg.readUnsignedInt(); if (dataLength > 0) { packet.setData(new byte[(int) dataLength]); msg.readBytes(packet.getData()); } else { packet.setData(null); } //Chunk id if (packet instanceof RpcPacket.ResponseChunkPacket) { ((RpcPacket.ResponseChunkPacket) packet).setChunkId(msg.readUnsignedShort()); } else if (packet instanceof RpcPacket.ResponseChunkAckPacket) { ((RpcPacket.ResponseChunkAckPacket) packet).setAckChunkId(msg.readUnsignedShort()); } return packet; } default: { RpcPacket packet = new RpcPacket(rpcType); packet.setPacketLength(totalPacketLength); //ack packet.setAck(ack); //data if (totalLength > 0) { packet.setData(new byte[(int) totalLength]); msg.readBytes(packet.getData()); } else { packet.setData(null); } return packet; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy