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

com.feingto.iot.common.codec.MessageDecoder Maven / Gradle / Ivy

There is a newer version: 2.3.3.RELEASE
Show newest version
package com.feingto.iot.common.codec;

import com.feingto.iot.common.Constants;
import com.feingto.iot.common.model.custom.LoginMessage;
import com.feingto.iot.common.model.custom.Message;
import com.feingto.iot.common.model.enums.MessageType;
import com.feingto.iot.common.util.ParserKit;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.CharsetUtil;

/**
 * 自定义报文长度解码器
 *
 * @author longfei
 */
public class MessageDecoder extends LengthFieldBasedFrameDecoder {
    /**
     * 头部信息大小(byte+int+byte = 1+4+1 = 6)
     */
    private static final int HEADER_SIZE = 6;

    private final int maxFrameLength;

    /**
     * @param maxFrameLength      网络字节序
     * @param lengthFieldOffset   长度字段偏移的字节数
     * @param lengthFieldLength   数据帧的最大长度
     * @param lengthAdjustment    该字段加长度字段等于数据帧的长度
     * @param initialBytesToStrip 数据帧中跳过的字节数
     * @param failFast            是否长度域超过maxFrameLength抛出TooLongFrameException
     */
    public MessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
                          int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
        super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);
        this.maxFrameLength = maxFrameLength;
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        in = (ByteBuf) super.decode(ctx, in);
        if (in == null || in.readableBytes() < HEADER_SIZE) {
            return null;
        }

        if (in.readableBytes() > this.maxFrameLength) {
            in.skipBytes(in.readableBytes());
        }

        // 标记包头位置
        in.markReaderIndex();

        // 判断是否非法头部
        if (in.readByte() != Constants.HEAD) {
            return null;
        }

        byte protocol = in.readByte();
        int length = in.readInt();

        // 判断数据包是否完整
        if (in.readableBytes() < length) {
            // 还原读指针
            in.resetReaderIndex();
            return null;
        }

        byte[] data = new byte[length];
        in.readBytes(data);
        // 判断是否非法尾部
        if (in.readByte() != Constants.TAIL) {
            return null;
        }

        String content = new String(data, CharsetUtil.UTF_8);
        if (protocol == MessageType.LOGIN.getValue()) {
            return new LoginMessage()
                    .id(ParserKit.decodeToString(content.substring(0, 64)))
                    .token(ParserKit.decodeToString(content.substring(64, 264)))
                    .username(ParserKit.decodeToString(content.substring(264, 304)))
                    .password(ParserKit.decodeToString(content.substring(304, 344)))
                    .type(ParserKit.decodeToString(content.substring(344, 348)));
        } else {
            return new Message().content(content).protocol(protocol);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy