[七]RabbitMQ-客户端源码之AMQPImpl+Method
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/rabbitmq-client-source-code-of-amqpimpl/
AMQPImpl類包括AMQP接口(public class AMQImpl implements AMQP)主要囊括了AMQP協議中的通信幀的類別。
這里以Connection.Start幀做一個例子。
public static class Connection {public static final int INDEX = 10;public static class Startextends Methodimplements com.rabbitmq.client.AMQP.Connection.Start{public static final int INDEX = 10;private final int versionMajor;private final int versionMinor;private final Map<String,Object> 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的全部。
| 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 |
附:本系列全集
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/rabbitmq-client-source-code-of-amqpimpl/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的[七]RabbitMQ-客户端源码之AMQPImpl+Method的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [六]RabbitMQ-客户端源码之AM
- 下一篇: [八]RabbitMQ-客户端源码之Ch