AMQP Illustrated

AMQP Illustrated

This blog post exposes some of the details of the AMQP protocol version 1.0. Code from the previous HelloWorld example is traced by Wireshark to capture the over-the-wire protocol details. The trace is rendered into a web page by Adverb, my AMQP comprehension tool that runs in a web server.

HelloWorld is an unrealistically simple use of AMQP. Real world applications need any number of more advanced techniques. That said, HelloWorld generates instances of every AMQP performative. For folks new to AMQP seeing lines of C# code together with the over-the-wire protocol packets will speed the learning process.

The goal here is to orient the reader and to expose all the details of a successful AMQP protocol operation.

Test Setup

For this test the nodes are:

Client IP address:    (Windows)
Broker IP address: (Linux)

Data Generation

  • Wireshark v1.12.7-0 running on the Windows client system traced the network activity.
  • A-MQ broker runs on the broker system.
  • HelloWorld runs on the client system.
  • Wireshark is stopped and the network trace is saved in a pcapng file.
  • The pcapng file is uploaded to Adverb running in a web server to generate the Adverb web page.

Adverb Analysis – The Web Page

The HelloWorld network trace web page is laid out with

  • Page controls
  • Connection data display control
  • AMQP frames
  • Decode legend
  • Notes

In the HelloWorld example there is only one connection. In the real world a Wireshark trace might have dozens of simultaneous connections and then showing just one or two connections at a time using Page control and Connection data display control has more value. For this example just ignore those controls skip down to the AMQP frames section to see the protocol operation.

Adverb Analysis

In this write-up individual lines from the HelloWorld source code are shown directly so a reference to the source is not strictly necessary. The HelloWorld network trace has the details of AMQP in action.

Open a Connection

Source code Line 14

Connection connection = new Connection(brokerAddr);

generates several network frames. The client and broker first open a TCP connection. Then they negotiate an AMQP protocol version that the connection should use. That happens in trace Frames 819, 822 where they exchange AMQP init messages and agree to use AMQP version 1.0.

Then the client and broker exchange AMQP Open performatives in Frames 837, 848 to create a connection. Note that the broker returns Offered-Capabilities and Properties in Frame 848. These will be explained in another more advanced post.

Begin a Session

Source code Line 15

Session session = new Session(connection);

generates a pair of AMQP Begin performatives in Frames 851, 878 to create a session. In Frame 851 the client is proposing the session creation by sending

* Channel 0
* Remote-Channel: null

This is a new session so the client has no remote channel. In Frame 878 the broker completes the session creation by sending

* Channel 0
* Remote Channel: 0

Over this connection a new session has been created. The client handle 0 is paired with the broker handle 0.

In Frame 878 the broker also sends an AMQP Flow performative giving the client session-level credits. Session-level flow control and credits will be explained in another post.

Attach Links

Source code Lines 17, 18

SenderLink sender = 
    new SenderLink(session, "sender", address);
ReceiverLink receiver = 
    new ReceiverLink(session, "receiver", address);

directly generate Frames 905 and 913 that create the sender and receiver links.

Sender Link

The client wants to send to address my_queue in the broker namespace. This is reflected in the AMQP Attach performative in trace Frame 905.

  • Attach performative
  • Link name: sender
  • Role: sender
  • Source: null
  • Target: my_queue

The broker responds by creating another link back to the client. This pair of links forms a full duplex channel over which the client and broker can exchange messages. Trace Frame 910 from the broker has the details of the broker’s link creation:

  • Attach performative
  • Link name: sender
  • Role: receiver
  • Source: null
  • Target: my_queue

The names of the links do not affect the communications over them and are not used outside of the Attach performative. The client can choose a link name that is descriptive, a random GUID string, or blank. The only restriction is that the ordered tuple of (Source, Target, Name) be unique.

A small point of confusion here may be that the broker creates a receiver link named “sender”. The A-MQ broker is simply mirroring the name of the client’s sender link when it creates the paired receiver link.

Note in Frame 910 the broker is also sending an AMQP Flow performative granting link-level credits. In this case the broker is sending the client enough credit so that the client may have up to 1000 messages outstanding on this link.

Receiver Link

The client’s receiver link and the corresponding broker’s sender link are created with a pattern similar to the client’s sender link.

In Frame 913 the client creates the link with:

  • Attach performative
  • Link name: receiver
  • Role: receiver
  • Source: my_queue
  • Target: null

The broker responds with Frame 940.

  • Attach performative
  • Link name: receiver
  • Role: sender
  • Source: my_queue
  • Target: null

A difference to note from the sender link pair creation is that the client did not issue any credit to the broker’s sender link. In this state even if the broker has messages available it will not send them.

Send a Message

Source code Line 21


generates trace Frame 973 and an AMQP Transfer frame that sends a message to the broker.

In this example the client sends the message with property

* Settled: false

This means that the client will keep the message in it’s outgoing message memory until the broker acknowledges it. For now the client still “owns” the message even though the message was successfully transferred over the wire to the broker. In AMQP terms the message is unsettled.

Transfer Ownership of Message to Broker

In trace Frame 1004 the broker sends an AMQP Disposition performative that passes ownership of the message from the client to the broker. Now the message is in the broker’s queue my_queue and the client forgets that the message ever existed. In AMQP terms the message is settled.

Receive a Message

Source code Line 23

Message helloIn = receiver.Receive();

directly generates Frame 1113 and indirectly generates Frame 1118.

In Frame 1113 the client sends an AMQP Flow performative that issues enough credit so that the broker can send 200 messages on the receiver link. The broker has one message in the queue and sends it to the client in the AMQP Transfer performative in Frame 1118.

Transfer Ownership of Message to Client

Source code Line 24


generated trace Frame 1123. The same message ownership that we just observed sending the message to the broker is not happening as the reply is transferred to the client. After receiving the AMQP Disposition performative the broker is free to remove the message from my_queue and forget that the message ever existed.

If the client did not call Accept then the broker would still have the message in the queue.

Closing the Links, Session, and Connection

Source code Lines 28..31


close the links, session, and connection in an orderly manner.

  • Frames 1127, 1130: AMQP Detach closes receiver link
  • Frames 1147, 1148: AMQP Detach closes sender link
  • Frames 1153, 1154: AMQP End closes the session
  • Frames 1165, 1166: AMQP Close closes the connection

Advanced Topics

AMQP 1.0 is a complete and powerful messaging protocol. Even a short tutorial like this touches on some parts of AMQP that are harder to explain. These are topics for upcoming blog posts:

  • Broker capabilities: ANONYMOUS-RELAY
  • Broker properties: topic-prefix, queue-prefix
  • Session and Link credit
  • Naming requirements
  • Delivery settlement mode: at-least-once, at-most-once, exactly-once
  • SASL user authentication

The HelloWorld example does not use AMQP.Net Lite advanced methods. Future posts should include AMQP.Net Lite:

  • Message and Application properties
  • Async IO and Task usage
  • AMQP addresses and message routing
  • ContainerHost abstraction

Finally I have to admit that a few code changes to the source were required to contrive the accompanying Adverb trace.

  • The source code shows a connection to a broker at localhost but the trace shows the broker at Wireshark doesn’t capture traffic to localhost on a Windows system. Moving the broker to another system made this capture possible.
  • Careful examination of the timestamps in the trace show that the frames are separated by hundreds of milliseconds. I deliberately injected delays into the code just to make the network trace pretty and understandable for an entry-level tutorial. Here is the same trace without the network delays. Note that the client fires off the Open, Begin, and Attach frames without waiting for any response from the broker and in Frame 1897 the broker sends six performatives back to the client. AMQP is designed to pipeline traffic and the AMQP.Net Lite client and A-MQ broker use pipelined messages to their advantage. Expect to see traffic patterns like this in your network.


A trivial HelloWorld AMQP.Net Lite application generates instances of all AMQP performatives. Using tools to capture and display the AMQP frames are helpful to learning and using AMQP correctly. Project Adverb distills Wireshark AMQP traces into comprehensible, dynamic web pages.

Happy Messaging!


A-MQ and AMQP.Net Lite with TLS/SSL

In this post I’m going to show how to encrypt the communications between the Red Hat JBoss A-MQ (A-MQ) broker and the AMQP.Net Lite (Lite) client.

  • Disclaimer: This article is a demonstration of the security concepts with concrete examples and recipes you can use for testing on a private network. It is not a manual for securing clients and brokers on a public network nor is it a tutorial on TLS/SSL in .NET or Java.


There are two levels of authentication that can be performed:

TLS Handshake

TLS provides an authenticated and secured communications channel. For simple TLS the broker must present a certificate that is signed by a certificate authority (CA) that the client trusts.

TLS Handshake with Client Certificate Request

The broker must always send a certificate to the client to start the secure channel with the TLS Handshake. Using a client certificate request the broker can demand that the client authenticate itself by returning a certificate to the broker. The client’s identity is securely embedded in the client certificate and by carefully controlling who gets the client certificates a system administrator may control who gets access to resources in the A-MQ broker.

This is useful for messaging environments where the broker must confirm the identity of the client with stronger authentication than just a username and password.

Security Providers

The Lite client and the A-MQ broker use different security providers for creating and managing SSL/TLS connections.

In either case we must configure the security provider with the proper certificates before the provider can set up secure SSL/TLS communication channels.

Certificate Generation Tools

In this example we are going to generate all the certificates locally. There are plenty of certificate generation tools from which to choose:

  • OpenSSL
  • Java Keytool
  • IBM KeyMan
  • Microsoft Makecert
  • Portecle
  • and more …

For this article I choose to use Java Keytool from Oracle to run on a Windows host. To get keytool, install Java Platform, Standard Edition (Java SE), and add the kit to your execution environment. These settings add version jdk1.7.0_79 to a process environment:

set java_home=c:\program files\java\jdk1.7.0_79
set      path=%path%;%java_home%\bin

Generate a set of certificates


The script generates all the certificates needed for TLS Handshake and Client Certificate exchange.
The steps to perform are:

  • Create a private, local Certificate Authority (the ‘CA’)
  • Create a key pair for the broker and sign it with CA
  • Import CA and broker certificates into broker keystore
  • Create a key pair for the client and sign it with CA
  • Import CA and client certificates into client keystore
  • Export client private key and certificate trust chain into a Personal Information Exchange
  • Create a trust store for the broker; import CA certificate into it

Configuration script changes required for your setup

In this script you need to adjust some variables to match the environment in which the scripts will be used.

  • CERT_LOC The folder where all the certificates are generated and stored. The default is .\certs and that is usually adequate for test purposes.
  • CA_CN The name of the self-signed certificate authority this script creates. There are no limits on this value but use some common sense and don’t create a name that conflicts with any public certificate authority.
  • BROKER_CN This name must be that public hostname of the broker system. This is the name in the connection URL that the client uses to access the broker.
  • CLIENT_CN This is the client’s username used in the client certificate.

For more complicated installations you may want more descriptive file names. The file path suffixes (.keystore, .truststore, .crt, .csr, .p12) are common for the content illustrated here.

Certificate generation script

Generate your certificate files with this script. Remember to edit CA_CN, BROKER_CN, and CLIENT_CN to fit your environment.

Distribute Certificates

On the broker system the broker configuration references files


On client systems that use only the TLS Handshake the client needs


On client systems that use TLS Handshake and Client Certificate the client needs


Configuring the Broker

Referencing the keystore and truststore files

There is no special installation required for the certificate files. They must be readable during broker start up.

Assume that you have run the generation script in the broker’s root folder. The certificates will be in folder .\certs. In the broker configuration file the key stores are loaded by adding these lines to file .\conf\activemq.xml.

    keyStore="${activemq.conf}/../certs/broker-jks.keystore" keyStorePassword="password"
    trustStore="${activemq.conf}/../certs/broker-jks.truststore" trustStorePassword="password">

Creating the AMQPS TLS Transport Connector for TLS Handshake Only

In file .\conf/activemq.xml add the A-MQ TLS/SSL AMQP connector

<transportConnector name="amqps" 

Creating the AMQPS TLS Transport Connector for TLS Handshake and Client Certificate

In file .\conf\activemq.xml add a qualifier to the AMQPS transport connector

<transportConnector name="amqps" 

Restart the broker. The TLS transport connector should be listening on port 5671.

Configuring the Client

Install the CA certificate

Client TLS Handshake is enabled by installing file ca.crt in the system’s Trusted Root Certification Authorities store.

  • From an Administrator command prompt run the MMC Certificate Manager plugin: certmgr.msc
  • Expand the Trusted Root Certification Authorities folder on the left to expose Certificates
  • Right click Certificates and select All Tasks -> Import…
  • Click Next
  • Browse to select file ca.crt
  • Click Next
  • Select Place all certificates in the following store
  • Select Certificate store : Trusted Root Certification Authorities
  • Click Next
  • Click Finish

The certificate issued by should appear in the Trusted Root Certification Authorities\Certificates list.

Use TLS Handshake Only

The client system is now configured to connect to the broker using TLS Handshake only. The client’s source code must be adjusted to select the TLS transport channel. In HelloWorld_simple.cs the broker URL uses an unsecured channel:

string broker = "amqp://guest:password@";

The client can connect to the secured channel by changing the scheme to amqps and the port number to 5671

string broker = "amqps://guest:password@"; 

Use TLS Handshake and Client Certificates

In order to use TLS and client certficates then the certificates with the client’s private keys must be imported into the proper certificate store on the client system.

  • From an Administrator command prompt run the MMC Certificate Manager plugin: certmgr.msc
  • Expand the Personal folder on the left to expose Certificates
  • Right click Certificates and select All Tasks -> Import…
  • Click Next
  • Click Browse
  • In the file type pulldown select Personal Information Exchange (\.pfx;*.p12)*
  • Select file client.p12 and press Open
  • Click Next
  • Type in the password for the private key: password. Accept default import options.
  • Click Next
  • Select Place all certificates in the following store
  • Select Certificate store : Personal
  • Click Next
  • Click Finish

Hello World Example Using Client Certificates

Before a client will return a certificate to the broker, the AMQP.Net Lite library must be told which certificates to use. The client certificate file client.crt is added to the list of certificates to be used during SChannel connection startup.


A complete example is found in HelloWorld-client-certs.cs. This source file and the supporting project files are available in the SDK.


My experience getting a setup to work usually involves several permission and connectivity issues.

  • Check that the broker process has permission to listen on AMQPS port 5671.
  • Make sure your broker host system has AMQPS port 5671 open. This may involve both Windows firewall and third party security software.
  • Check that the rest of your infrastructure allows traffic to port 5671, too.

Still can’t connect? Fortunately, both the client and the broker have built-in facilities for troubleshooting SSL/TLS issues.

AMQP.Net Lite

The Lite library uses SChannel to open the secure connection. When any SSL/TLS error happens the caller is only informed of “SSL Handshake failed”. Detailed logging must be enabled through a registry setting. See How to enable Schannel event logging in IIS for detailed instructions and the usual warnings about registry modification. Essentially this registry key has values which are logically ORed together:


Value Name: EventLogging
Data Type: REG_DWORD

Value  Description
=====  ===========
0x0    Do not log
0x1    Log error messages
0x2    Log warnings
0x4    Log information and success events

The Lite library has internal event logging but in the case of an SSL/TLS handshake failure Lite does not receive detailed event information from SChannel.


Logging in the Java SSL code may enabled by starting the broker with

The Red Hat JBoss A-MQ broker is fully supported by Red Hat.


With the proper certificates AMQP.Net Lite clients may use TLS Handshake encrypted channels when communicating with Red Hat JBoss A-MQ brokers. Advanced authentication may be performed with TLS Client Certificates.

Happy Messaging!

Hello World!

Red Hat JBoss AMQP.Net Lite Client – Hello World!

AMQP.Net Lite is a lightweight AMQP 1.0 library for .NET.

This article describes how to install and use the library packaged in the Red Hat JBoss A-MQ .NET Lite SDK. The example connects to services in a Red Hat JBoss A-MQ broker.

Download/Install AMQP.Net Lite

AMQP.Net Lite is available from a number of sources. The one you pick depends on your needs.

  • Red Hat JBoss A-MQ AMQP.Net Lite Client SDK
  • NuGet
  • Git

Red Hat JBoss A-MQ AMQP.Net Lite Client SDK

As part of Red Hat JBoss A-MQ 6.2 Red Hat supplies an SDK for AMQP.Net Lite. The SDK has precompiled binary library files for use on a Windows desktop system running Visual Studio 2012 or Visual Studio 2013, AMQP.Net Lite API documentation, and a set of example programs. This is an ideal environment for getting started with .NET and AMQP.


Download the SDK from Red Hat JBoss A-MQ – Downloads. On the download page choose .NET Lite SDK. This will result in downloading a single file:


Installing AMQP.Net Lite consists of unzipping the distribution file. This may be done using Windows Explorer or by a third party utility such as 7-Zip.

A typical unzipped installation will look like this:

W:\> dir
 Directory of W:\

06/18/2015  03:58 PM    <DIR>          amqpnetlite
06/03/2015  01:00 PM         1,020,150

Inside the amqpnetlite folder you will find the Visual Studio 2012 and 2013 solution files and the other files that make up the kit.

W:\> dir amqpnetlite
 Directory of W:\\amqpnetlite

05/27/2015  01:20 PM            12,757 amqp-vs2012.sln
05/27/2015  01:20 PM            12,837 amqp.sln
06/11/2015  04:53 PM    <DIR>          bin
06/11/2015  04:53 PM    <DIR>          doc
06/11/2015  04:53 PM    <DIR>          Examples
05/27/2015  01:20 PM             3,763 README-amqpnetlite.txt


AMQP.Net Lite is available through the Package Manager Console integrated with Visual Studio. Users will find this method of installation very convenient but the process does not install examples nor supporting documentation. I’d recommend the NuGet package for experienced users who just need the runtime library bits and don’t need help getting started.

To install using NuGet issue the following command in the Package Manager Console

Install-Package AMQPNetLite

Git from upstream

The upstream project is open source. Visit the home page.

The source code is available at

git clone

The upstream project is open source on github. Visit the home page.

The source code is available at

git clone

The project supports a variety of .NET Frameworks:

  • .NET 3.5
  • .NET 4.0
  • .NET Core
  • Windows Phone
  • Windows RT
  • Windows Store
  • Compact Framework
  • Micro Framework

When you try to build a fresh source from upstream is it unlikely that your system will have all of the .NET packages required to support everything AMQP.Net Lite offers. While loading the solution file Visual Studio emits a series of errors as it removes projects that can not compile on your system now. Not to worry, though, as projects reappear when the underlying support for them is installed.

The upstream project also includes dozens of self tests that illustrate how things are supposed to work. These are a great reference.

AMQP 1.0

AMQP.Net Lite uses only AMQP version 1.0 and interoperates with a system such as the JBoss A-MQ broker that also uses AMQP 1.0.

A brief introduction to the AMQP 1.0 messaging protocol is in order. The AMQP.Net Lite programming API closely models the structures defined by AMQP 1.0. If one is familiar with AMQP 1.0 then one understands most of the relationships in the messaging aspects of AMQP.Net Lite.


A Connection is a full-duplex, reliably ordered sequence of frames, or units of work, carried over the communication wire.

  • AMQP requires guarantees similar to what TCP or SCTP provide for byte streams.
  • A single AMQP Connection is established for each underlying transport (TCP) connection.


Within a Connection a Session is a grouping of some number of independent unidirectional channels.

  • Sessions provide sequencing and flow control at the frame transfer level.
  • A Connection may contain any number of Sessions.


Within a Session a Link is a unidirectional route between a source and a target, one at each end of the Connection.

  • Links are the paths over which messages are transferred.
  • Links are unidirectional.
  • Pairs of links are bound to create full duplex communication channels between endpoints.
  • A single Session may be associated with any number of Links.
  • Links provide flow control at the message transfer level.

From a client’s point of view the source and target are names of the terminus objects in the connection peer’s namespace. The SenderLink target name and ReceiverLink source name are the names of queues or topics in the broker.

The example code sends and receives messages to and from a queue named my_queue. The JBoss A-MQ broker may autocreate this queue if it does not already exist. Note that the JBoss A-MQ broker may be configured with a security setting that restricts queue autocreation. With that restriction then my_queue must be created administratively before the example will work.


AMQP 1.0 Messaging has a rich and well structured design to suit virtually any message use case. In the example only a simple message consisting of a text string is used. Real world applications are typically much more demanding and will use more advanced messaging properties and capabilities.

Hello World Example

Let’s get going with HelloWorld. This example is file HelloWorld-simple.cs in the SDK.

Source Code

 1 using System;
 2 using Amqp;
 4 namespace HelloWorld
 5 {
 6   class HelloWorld
 7   {
 8     static void Main(string[] args)
 9     {
10       string brokerUrl = "amqp://localhost:5672";
11       string address   = "my_queue";
13       Address    brokerAddr = new Address(brokerUrl);
14       Connection connection = new Connection(brokerAddr);
15       Session    session    = new Session(connection);
17       SenderLink   sender   = new   SenderLink(session, "sender",   address);
18       ReceiverLink receiver = new ReceiverLink(session, "receiver", address);
20       Message helloOut = new Message("Hello World!");
21       sender.Send(helloOut);
23       Message helloIn = receiver.Receive();
24       receiver.Accept(helloIn);
26       Console.WriteLine(helloIn.Body.ToString());
28       receiver.Close();
29       sender.Close();
30       session.Close();
31       connection.Close();
32     }
33   }
34 }

The source is also available here

Code Notes

  • Line 2 The using directive enables unqualified use of the AMQP.Net Lite objects in the AMQP namespace.
  • Line 10 contains the URL specifying the network address of the A-MQ broker to which this connection is directed. The details of the URL format are explained below.
  • Line 11 has the name of the resource in the broker to which and from which links will be created.
  • Line 13 creates an Address object that holds the parsed URL.
  • Line 14 opens the connection:
    • A TCP connection is opened
    • AMQP Version information is exchanged and accepted
    • AMQP Open performatives are exchanged to create an AMQP Connection and to define Connection-level capabilities and properties.
  • Line 15 creates a session:
    • AMQP Begin performatives are exchanged to create an AMQP Session and to define Session-level values and limits.
  • Lines 17 and 18 create links to the resource in the broker.
    • AMQP Attach performatives are exchanged to create AMQP Links and to define Link-level names, values, and properties.
    • The broker issues AMQP Flow performatives to define credits that allow the client to send messages.
  • Line 20 creates a message holding a simple text string
  • Line 21 sends the message on the sender link
    • The client sends an AMQP Transfer performative containing the original message.
    • The broker sends an AMQP Disposition performative acknowledging and assuming ownership of the message. The broker puts the message into the my_queue queue.
  • Line 23 receives a message on the receiver link.
    • The broker sends an AMQP Transfer performative containing the reply message.
    • Note: The receiver will time out and throw an exception if no message is received
    • The client issues an AMQP Flow performative to replenish the broker’s credits for sending to the reply link.
  • Line 24 The receiver accepts the message.
    • The client sends an AMQP Disposition performative acknowledging and assuming ownership of the message. The broker removes the message from the my_queue queue.
    • Note: if the client did not accept the message then the message would remain on the broker queue.
  • Line 26 prints “Hello World!”
  • Lines 28 and 29 close the receiver and sender links
    • AMQP Detach performatives are exchanged to dispose of the links.
  • Line 30 closes the session
    • AMQP End performatives are exchanged to dispose of the session.
  • Line 31 closes the connection and releases internal resources related to it
    • The client and broker exchange AMQP Close performatives to dispose of the connection.
    • The TCP connection between the client and broker is torn down.

AMQP.Net Lite Connection Specification

AMQP.Net Lite accepts a formatted URL to specify the peer address.

amqp[s] :// [user:[password]@] domain[:port] [/path]
  1. The scheme
    • amqp specifies an unencrytped connection
    • amqps specifies an encrypted connection.
  2. user and password are optional credentials. When specified AMQP.Net Lite uses them during the SASL negotiation phase of AMQP connection establishment.
  3. domain is the domain name or literal IP numeric address of the target peer system.
  4. port number, given in decimal, is optional. If omitted, the default for the scheme is used:
    • 5672 for amqp
    • 5671 for amqps
  5. path is part of the parsed Address class but is not used as part of the connection.


Using AMQP.Net Lite it is easy to get going in the AMQP messaging space. With AMQP you can operate with Red Hat A-MQ brokers and with services in the Azure cloud with equal ease.

In a future blog post I want to share how to secure your AMQP communications with TLS/SLL.

Happy Messaging!