自动化立体仓库 - WCS系统
zhangc
2025-03-11 d5449236ef0b3adafb3e4cc872f50479efa0ce7b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.zy.core.netty.handle;
 
import com.core.common.SnowflakeIdWorker;
import com.zy.core.netty.constant.Constant;
import com.zy.core.netty.domain.ChPackage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
 
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
 
/**
 * Created by vincent on 2019-04-10
 */
public class ProtocolDecoder extends ByteToMessageDecoder {
 
    private final SnowflakeIdWorker snowflakeIdWorker;
 
    public ProtocolDecoder(SnowflakeIdWorker snowflakeIdWorker) {
        this.snowflakeIdWorker = snowflakeIdWorker;
    }
 
 
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> list) throws Exception {
        int startMark = indexOfStartMark(in);
        if (startMark == -1) {
            return;
        }
        // 去除无用前缀报文
        if (startMark != 0) {
            in.readerIndex(startMark);
            in.discardReadBytes();
        }
        // 生成和初始化消息包装类
 
        String ip = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
        ChPackage pac = ChPackage.valueOfEmpty(String.valueOf(snowflakeIdWorker.nextId()), ip);
 
        pac.setSourceBuff(in);
 
        // 解析
        list.add(analyzeProtocol(pac));
    }
 
    public ChPackage analyzeProtocol(ChPackage pac) {
 
        ByteBuf byteBuf = pac.getSourceBuff();
 
        // 备份缓冲区
        ByteBuf body = byteBuf.duplicate();
        if (null != body && body.readableBytes() >= 0) {
            pac.setContent(body);
        } else {
            return null;
        }
 
        // 字节数组
        body.resetReaderIndex();
        byte[] bytes = new byte[body.readableBytes()];
        body.readBytes(bytes);
        body.resetReaderIndex();
        pac.setBytes(bytes);
 
        // ascii
        if (bytes.length > 0) {
            pac.setAscii(new String(pac.getBytes(), StandardCharsets.US_ASCII));
        }
 
        // 备份字符串
        if (null != pac.getSourceBuff() && null == pac.getSourceHexStr()) {
            pac.getSourceBuff().resetReaderIndex();
            pac.setSourceHexStr(ByteBufUtil.hexDump(pac.getSourceBuff()));
            pac.getSourceBuff().resetReaderIndex();
        }
 
        byteBuf.skipBytes(byteBuf.readableBytes());
//        pac.getSourceBuff().readByte();
 
        return pac;
    }
 
    // 获取标识位下标
    private int indexOfStartMark(ByteBuf inputBuffer) {
        int length = inputBuffer.writerIndex();
        // 报文长度至少大于2
        if (length < 2) {
            return -1;
        }
        int readerIndex = inputBuffer.readerIndex();
        for (int i = readerIndex; i < length - 1; i++) {
            byte b1 = inputBuffer.getByte(i);
            // "#" = b1
            if (0x23 == b1) {
                // "#" = b2
                if (i + 1 <= length && 0x23 == inputBuffer.getByte(i + 1)) {
                    return i;
                }
            }
        }
        return -1;
    }
 
    private String byte2Str(ByteBuf buf, int len) {
        byte[] bytes = new byte[len];
        buf.readBytes(bytes);
        return new String(bytes, Constant.CHARSET_GBK);
    }
 
}