Pigeon源码分析 -- 服务端解码消息格式

本文简单分析下pigeon请求的消息格式

先看一个类  com.dianping.pigeon.remoting.netty.codec.FrameDecoder

@Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer)
            throws Exception {

        Object message = null;

        if (buffer.readableBytes() <= 2) {
            return message;
        }

        byte[] headMsgs = new byte[2];

        buffer.getBytes(buffer.readerIndex(), headMsgs);

        if ((0x39 == headMsgs[0] && 0x3A == headMsgs[1])) {
            //old protocol
            message = doDecode(buffer);

        } else if ((byte) 0xAB == headMsgs[0] && (byte) 0xBA == headMsgs[1]) {
            //new protocol
            message = _doDecode(buffer);

        } else {
            throw new IllegalArgumentException("Decode invalid message head:" +
                    headMsgs[0] + " " + headMsgs[1] + ", " + "message:" + buffer);
        }

        return message;

    }

我们这里看新协议

protected Object _doDecode(ChannelBuffer buffer)
            throws Exception {
        CodecEvent codecEvent = null;

        if (buffer.readableBytes() <= CodecConstants._FRONT_LENGTH) {//这个buffer长度比真正消息体前的字节数还少,那就别读了
            return codecEvent;
        }

        int totalLength = (int) (buffer.getUnsignedInt(
                buffer.readerIndex() +
                        CodecConstants._HEAD_LENGTH));//这里正好说明头部四个字节之后的4个字节正是表示真正的消息体长度

        int frameLength = totalLength + CodecConstants._FRONT_LENGTH_; 
     //public static final int _FRONT_LENGTH_ = _HEAD_LENGTH + _TOTAL_FIELD_LENGTH;//4 + 4
     //frameLength表示消息头加消息体长度
if (buffer.readableBytes() >= frameLength) { ChannelBuffer frame = buffer.slice(buffer.readerIndex(), frameLength); buffer.readerIndex(buffer.readerIndex() + frameLength); codecEvent = new CodecEvent(frame, true); codecEvent.setReceiveTime(System.currentTimeMillis()); } return codecEvent; }

    

    第二个4个字节表示的是消息体的长度,这里要注意消息体中前2个字节是请求头,而不是真实的请求数据。

    第一个4个字节表示的东西很多

    

第1-2个字节固定为十六进制的0xAB、0xBA,即十进制的171、186,或8位有符号整型的-85、-70,可以用来区分是默认协议还是统一协议。
第3个字节为协议版本,也可以称作command字节,会用来定义编解码的相关自定义行为,如压缩方式、数据校验方式等,具体command第8位表示是否需要进行校验数据完整性,第6、7位定义了是否进行压缩及具体的压缩方式。
第4个字节为序列化方式,一般为1。
第5~8个字节为消息体长度。
  引用自 【Pigeon源码阅读】RPC底层通信实现原理(八)_总结沉淀-CSDN博客

 

总结:

  像这样的设计协议,我看就挺好了,消息头四个字节固定,然后四个字节表示消息体长度,总长度是消息体长度 + 4 + 4

  

 

posted on 2021-05-25 10:02  MaXianZhe  阅读(105)  评论(0编辑  收藏  举报

导航