七、RabbitMQ-客户端源码之AMQPImpl+Method

作者:朱小厮 | 出自:https://hiddenpps.blog.csdn.net/column/info/14800

AMQPImpl类包括AMQP接口(public class AMQImpl implements AMQP)主要囊括了AMQP协议中的通信帧的类别。

这里以Connection.Start帧做一个例子。

public static class Connection {
    public static final int INDEX = 10;
    public static class Start
        extends Method
        implements com.rabbitmq.client.AMQP.Connection.Start
    {
        public static final int INDEX = 10;
        private final int versionMajor;
        private final int versionMinor;
        private final Map
   
     
      
     serverProperties;
        private final LongString mechanisms;
        private final LongString locales;
....//下面省略很多代码。。。
   
     

可以看到Start类是Connection类的内部静态子类,表示此Start类为Connection.Start,而且Start类是继承Method方法的,包括接下来所有的AMQP协议帧都是继承这个Method方法,Method可以看成用来区分AMQP协议帧的类型。

Method类是一个抽象类(Base class for AMQP method objects, specialized by autogenerated code in AMQP.java),我们来看下Method类的代码:

public abstract class Method implements com.rabbitmq.client.Method {
    /** {@inheritDoc} */
    public abstract int protocolClassId(); /* properly an unsigned short */
    /** {@inheritDoc} */
    public abstract int protocolMethodId(); /* properly an unsigned short */
    /** {@inheritDoc} */
    public abstract String protocolMethodName();
    /**
     * Tell if content is present.
     * @return true if the wire-protocol for this method should involve a content header and body,
     * or false if it should just involve a single method frame.
     */
    public abstract boolean hasContent();
    /**
     * Visitor support (double-dispatch mechanism).
     * @param visitor the visitor object
     * @return the result of the "visit" operation
     * @throws IOException if an error is encountered
     */
    public abstract Object visit(MethodVisitor visitor) throws IOException;
    /**
     * Private API - Autogenerated writer for this method.
     * @param writer interface to an object to write the method arguments
     * @throws IOException if an error is encountered
     */
    public abstract void writeArgumentsTo(MethodArgumentWriter writer) throws IOException;
    /**
     * Public API - debugging utility
     * @param buffer the buffer to append debug data to
     */
    public void appendArgumentDebugStringTo(StringBuilder buffer) {
        buffer.append("(?)");
    }
    @Override public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("#method<").append(protocolMethodName()).append(">");
        this.appendArgumentDebugStringTo(sb);
        return sb.toString();
    }
    public Frame toFrame(int channelNumber) throws IOException {
        Frame frame = new Frame(AMQP.FRAME_METHOD, channelNumber);
        DataOutputStream bodyOut = frame.getOutputStream();
        bodyOut.writeShort(protocolClassId());
        bodyOut.writeShort(protocolMethodId());
        MethodArgumentWriter argWriter = new MethodArgumentWriter(new ValueWriter(bodyOut));
        writeArgumentsTo(argWriter);
        argWriter.flush();
        return frame;
    }

代码不长。挑几个解释下。

protocolClassId()和protocolMethodId():每一个Method(Connection.Start/.StartOk, Connection.Tune/.TuneOk等等)都包含classId和methodId,可以参考下图:

 

protocolMethodName()返回本Method的名称,比如Connection.Start的就是:

public String protocolMethodName() { return "connection.start";}

boolean hasContent()用来区分这个Method之后是否有Content-Body,比如Connection.Start的为:

public boolean hasContent() { return false; }

又比如Basic.Publish的为:

public boolean hasContent() { return true; }


好了,这里可以回来接着讲AMQPImpl了。

下面是一张表,用来涵盖AQMP协议各个种类的Method以及其一些属性,看完这张表就看完了AMQPImpl的全部。

Method-Name classId methodId hasContent
Connection.Start 10 10 false
Connection.StartOk 10 11 false
Connection.Secure 10 20 false
Connection.SecureOk 10 21 false
Connection.Tune 10 30 false
Connection.TuneOk 10 31 false
Connection.Open 10 40 false
Connection.OpenOk 10 41 false
Connection.Close 10 50 false
Connection.CloseOk 10 51 false
Connection.Blocked 10 60 false
Connection.Unblocked 10 61 false
Channel.Open 20 10 false
Channel.OpenOk 20 11 false
Channel.Flow 20 20 false
Channel.FlowOk 20 21 false
Channel.Close 20 40 false
Channel.CloseOk 20 41 false
Access.Request 30 10 false
Access.RequestOk 30 11 false
Exchange.Declare 40 10 false
Exchange.DeclareOk 40 11 false
Exchange.Delete 40 20 false
Exchange.DeleteOk 40 21 false
Exchange.Bind 40 30 false
Exchange.BindOk 40 31 false
Exchange.Unbind 40 40 false
Exchange.UnbindOk 40 51 false
Queue.Declare 50 10 false
Queue.DeclareOk 50 11 false
Queue.Bind 50 20 false
Queue.BindOk 50 21 false
Queue.Purge 50 30 false
Queue.PurgeOk 50 31 false
Queue.Delete 50 40 false
Queue.DeleteOk 50 41 false
Queue.Unbind 50 50 false
Queue.UnbindOk 50 51 false
Basic.Qos 60 10 false
Basic.QosOk 60 11 false
Basic.Consume 60 20 false
Basic.ConsumeOk 60 21 false
Basic.Cancel 60 30 false
Basic.CancelOk 60 31 false
Basic.Publish 60 40 true
Basic.Return 60 50 true
Basic.Deliver 60 60 true
Basic.Get 60 70 false
Basic.GetOk 60 71 true
Basic.GetEmpty 60 72 false
Basic.Ack 60 80 false
Basic.Reject 60 90 false
Basic.RecoverAsync 60 100 false
Basic.Recover 60 110 false
Basic.RecoverOk 60 111 false
Basic.Nack 60 120 false
Tx.Select 90 10 false
Tx.SelectOk 90 11 false
Tx.Commit 90 20 false
Tx.CommitOk 90 21 false
Tx.Rollback 90 30 false
Tx.RollbackOk 90 31 false
Confirm.Select 85 10 false
Confirm.SelectOk 85 11 false