com.feingto.iot.common.codec.MessageDecoder Maven / Gradle / Ivy
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