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

com.gateway.connector.tcp.codec.TcpProtoDecoder Maven / Gradle / Ivy

package com.gateway.connector.tcp.codec;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gateway.connector.proto.Proto;
import com.gateway.connector.utils.ProtoUtils;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

public class TcpProtoDecoder extends ByteToMessageDecoder {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private boolean isGzip = false;

	public TcpProtoDecoder(boolean isGzip) {
		this.isGzip = isGzip;
	}

	@Override
	protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list)
			throws Exception {

		// while (true)
		{
			Proto proto = parseFrom(byteBuf);
			if (proto != null) {
				list.add(proto);
				logger.debug("decode: {}", proto);
			} else {
				// break;
			}
		}
	}

	public Proto parseFrom(ByteBuf byteBuf) {
		if (!byteBuf.isReadable(Proto.HEADER_LENGTH))
			return null;

		int index = byteBuf.readerIndex();
		int len = byteBuf.readInt();

		if (len < Proto.HEADER_LENGTH || !byteBuf.isReadable(len - Integer.BYTES)) {

			byteBuf.readerIndex(index);
			return null;
		}

		Proto proto = new Proto();
		proto.setPacketLen(len);
		proto.setHeaderLen(byteBuf.readShort());
		proto.setCmd(byteBuf.readInt());
		proto.setFormat(byteBuf.readShort());
		proto.setSeq(byteBuf.readInt());
		int sidLength = byteBuf.readInt();
		if (sidLength > 0) {
			byte[] sidByte = new byte[sidLength];
			try {
				byteBuf.readBytes(sidByte);

			} catch (Exception e) {
				logger.warn("readBytes:{},readableBytes:{},PacketLen:{},HeaderLen:{},Cmd:{},Format:{},Seq:{}",
						sidLength, byteBuf.readableBytes(), proto.getPacketLen(), proto.getHeaderLen(), proto.getCmd(),
						proto.getFormat(), proto.getSeq(), e);
				byteBuf.readerIndex(index);
				return null;
			}
			proto.setSessionId(new String(sidByte));
		}
		int protSize = len - Proto.HEADER_LENGTH - sidLength;
		if (protSize > 0) {
			try {
				ByteBuf buffer = byteBuf.readSlice(protSize);

				byte[] req = new byte[protSize];
				buffer.readBytes(req);
				proto.setBody(ProtoUtils.ungzipBody(isGzip, req));
			} catch (Exception e) {
				logger.warn("readSlice:protSize:{},readableBytes:{}", protSize, byteBuf.readableBytes(), e);
				byteBuf.readerIndex(index);
				return null;
			}

		}
		return proto;
	}
}