• 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

      

  • 相关阅读:
    Android中实现定时器的三种方法 分类: Android 2015-07-14 18:04 11人阅读 评论(0) 收藏
    java构造器内部多态方法
    java继承方法覆盖
    java对象实例化 静态块,对象块,构造函数执行顺序
    Linux 的系统运行级别
    Jmeter启动jmeter-server.bat 报java.io.FileNotFoundException:rmi_keystore.jks 解决方法
    jmeter中JSON Extractors使用
    CentOS6.5下安装jenkins
    day12接口自动化测试框架
    day10 python接口开发、mock接口、网络编程
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14807464.html
Copyright © 2020-2023  润新知