Chapter 7. Network Connections: Protocols

AMQ Broker has a pluggable protocol architecture that allows you to easily enable one or more protocols for a network connection.

The broker ships with support for the following protocols:

Note

In addition to the protocols above, the broker also supports its own highly performant native protocol known as "Core". Past versions of this protocol were known as "HornetQ" and used by Red Hat JBoss Enterprise Application Platform.

7.1. Configuring a Network Connection to Use a Protocol

You must associate a protocol with a network connection before you can use it. (See Network Connections: Acceptors and Connectors for more information on how to create and configure network connections.) The default configuration, located in the file BROKER_INSTANCE_DIR/etc/broker.xml, comes with a number of connections already defined. In fact, there is an acceptor for each of the supported protocols, plus a default acceptor that supports all protocols.

Default acceptors in broker.xml

<configuration>
  <core>
    ...
    <acceptors>
      <!-- Default ActiveMQ Artemis Acceptor.  Multi-protocol adapter.  Currently supports ActiveMQ Artemis Core, OpenWire, STOMP, AMQP, MQTT, and HornetQ Core. -->
      <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576</acceptor>

      <!-- AMQP Acceptor.  Listens on default AMQP port for AMQP traffic.-->
      <acceptor name="amqp">tcp://0.0.0.0:5672?protocols=AMQP</acceptor>

      <!-- STOMP Acceptor. -->
      <acceptor name="stomp">tcp://0.0.0.0:61613?protocols=STOMP</acceptor>

      <!-- HornetQ Compatibility Acceptor.  Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
      <acceptor name="hornetq">tcp://0.0.0.0:5445?protocols=HORNETQ,STOMP</acceptor>

      <!-- MQTT Acceptor -->
      <acceptor name="mqtt">tcp://0.0.0.0:1883?protocols=MQTT</acceptor>
    </acceptors>
    ...
  </core>
</configuration>

Note that the only requirement to enable a protocol is to add the protocols parameter to the URI query string. The value of the parameter should be a comma separated list of protocol names. If the protocol parameter is omitted from the URI all protocols are enabled.

For example, to create a new acceptor that will enable the broker to begin receiving messages on port 3232 using the AMQP protocol, follow these steps:

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add the following line to the <acceptors> stanza:
<acceptor name="ampq">tcp://0.0.0.0:3232?protocols=AMQP</acceptor>

7.2. Using AMQP with a Network Connection

The broker supports the AMQP 1.0 specification. An AMQP link is a uni-directional protocol for messages between a source and a target, that is, a client and the broker.

Enabling a Network Connection to Use AMQP

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add or configure an acceptor to receive AMQP clients by including the protocols parameter with a value of AMQP as part of the URI, like so:
<acceptors>
  <acceptor name="amqp-acceptor">tcp://localhost:5672?protocols=AMQP</acceptor>
  ...
</acceptors>

In the above example, the broker will then accept AMQP 1.0 clients on port 5672 which is the default AMQP port.

A link will have an endpoint of which there are two kinds, a sender and a receiver. At the broker, a sender will have its messages converted into a broker message and forwarded to its destination or target. A receiver will map onto a broker’s consumer and convert broker messages back into AMQP messages before being delivered.

If an AMQP link is dynamic, a temporary queue is created and either the remote source or the remote target address will be set to the name of the temporary queue. If the link is not dynamic, the address of the remote target or source is used for the queue. If the remote target or source does not exist, an exception is sent.

An AMQP links target can also be a Coordinator, the Coordinator is used to handle transactions. If a coordinator is used the underlying session is transacted and is either rolled back or committed via the coordinator.

Note

AMQP allows the use of multiple transactions per session, amqp:multi-txns-per-ssn, however the current version of AMQ Broker will support only single transactions per session.

See the AMQP 1.0 specification for more information about the protocol and its features.

7.2.2. Configuring AMQP Security

The broker supports AMQP SASL Authentication. See Security for more information on how to configure SASL-based authentication on the broker.

7.3. Using MQTT with a Network Connection

The broker supports MQTT v3.1.1 (and also the older v3.1 code message format). MQTT is a lightweight, client to server, publish/subscribe messaging protocol. MQTT has been specifically designed to reduce messaging overhead (and thus network traffic) and code footprint on client devices. For this reason MQTT is ideally suited to constrained devices such as sensors and actuators and is quickly becoming the de facto standard communication protocol for Internet of Things(IoT).

Enabling a Network Connection to Use the MQTT Protocol

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add an acceptor with the MQTT protocol enabled. For example:
<acceptors>
  <acceptor name="mqtt">tcp://localhost:1883?protocols=MQTT</acceptor>
  ...
</acceptors>

MQTT comes with a number of useful features including:

Quality of Service
Each message can define a quality of service that is associated with it. The broker will attempt to deliver messages to subscribers at the highest quality of service level defined.
Retained Messages
Messages can be "retained" for a particular address. New subscribers to that address receive the last sent retained message before any other messages, even if the retained message was sent before the client connected.
Wild card subscriptions
MQTT addresses are hierarchical much like a file system. Clients are able to subscribe to specific topics or to whole branches of a hierarchy.
Will Messages
Clients are able to set a "will message" as part of their connect packet. If the client abnormally disconnects, the broker will publish the will message to the specified address. Other subscribers receive the will message and can react accordingly.

The best source of information on the MQTT protocol is in the specification. The MQTT v3.1.1 specification can be downloaded from the OASIS website

7.4. Using OpenWire with a Network Connection

The broker supports the OpenWire protocol, which allows a JMS client to talk directly to a broker. Use this protocol to communicate with older versions of AMQ Broker.

Currently AMQ Broker supports OpenWire clients that are using standard JMS APIs only. Future releases should offer support for some advanced, OpenWire specific features.

Enabling a Network Connection to Use the OpenWire Protocol

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add or modify an acceptor so that it includes OPENWIRE as part of the protocol parameter, like so:

    <acceptors>
      <acceptor name="openwire-acceptor">tcp://localhost:61616?protocols=OPENWIRE</acceptor>
      ...
    </acceptors>

In the example above, the broker will listen on port 61616 for incoming OpenWire commands.

For more details, refer to the examples located under INSTALL_DIR/examples/protocols/openwire.

7.5. Using Stomp with a Network Connection

Stomp is a text-orientated wire protocol that allows Stomp clients to communicate with Stomp Brokers. The broker supports Stomp 1.0, 1.1 and 1.2.Stomp clients are available for several languages and platforms making it a good choice for interoperability.

Enabling a Network Connection to Use the Stomp Protocol

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Configure an existing acceptor or create a new one and include a protocols parameter with a value of STOMP, as below.
<acceptors>
  <acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP</acceptor>
  ...
</acceptors>

In the example above, the broker will accept Stomp connections on the port 61613, the default port for Stomp brokers.

See the stomp example located under INSTALL_DIR/examples/protocols which shows how to configure a broker with Stomp.

7.5.1. Knowing the Limitations When Using Stomp

There are a couple of limitations to keep in mind when using Stomp with AMQ Broker

  1. The broker currently does not support virtual hosting, which means the 'host' header in CONNECT frame will be ignored.
  2. Message acknowledgements are not transactional. The ACK frame can not be part of a transaction (it will be ignored if its transaction header is set).

7.5.2. Providing IDs for Stomp Messages

When receiving Stomp messages via a JMS consumer or a QueueBrowser, the messages by default will not contain any JMS properties, such as JMSMessageID. Because this may inconvenience clients who want to use an ID, the broker provides a parameter to set a message ID on each incoming Stomp message.

Providing Each Stomp Message with a Unique ID

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Set the stompEnableMessageId parameter to true for the acceptor used for STOMP connections, as in the example below:
<acceptors>
  <acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompEnableMessageId=true</acceptor>
  ...
</acceptors>

When the server starts with the above setting, each stomp message sent through this acceptor will have an extra property added. The property key is amq-message-id and the value is a String representation of a long type internal message id prefixed with “STOMP”, like:

amq-message-id : STOMP12345

If stomp-enable-message-id is not specified in the configuration, the default is false.

7.5.3. Handling Large Messages

Stomp clients may send very large bodies of frames which can exceed the size of the brokers server’s internal buffer, causing unexpected errors.

To prevent this situation from happening, set the acceptor’s stompMinLargeMessageSize parameter to an appropriate size. The broker will check the size of the body of each Stomp frame coming from connections established with this acceptor. If the size of the body is equal to or greater than the value of stompMinLargeMessageSize, the message will be persisted as a large message.

Setting a Value for stompMinLargeMessageSize.

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add the stompMinLargeMessageSize parameter and its desired value to an existing or new acceptor, as in the example below.
<acceptors>
  <acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompMinLargeMessageSize=10240</acceptor>
  ...
</acceptors>

In the example above, the broker is configured to accept STOMP messages on port 61613. If the acceptor receives a STOMP frame with body larger than or equal to 10240 bytes the broker will persist it as a large message.

When a large message is delivered to a stomp consumer, the broker will automatically handle the conversion from a large message to a normal message, before sending it to the client.If a large message is compressed, the server will uncompressed it before sending it to stomp clients.

The default value of stompMinLargeMessageSize is 102400 bytes.

7.5.4. Setting a Connection’s Time to Live (TTL)

STOMP clients should always send a DISCONNECT frame before closing their connections, which will allow the server to clear up any server side resources, such as sessions and consumers. However, if STOMP clients exit without sending a DISCONNECT frame, or if they crash, the server will have no way of knowing immediately whether the client is still alive. STOMP connections therefore are configured to have a "Time to Live" (TTL) of 1 minute. The means that the broker will terminate the connection to the STOMP client if the connection has been idle for a minute or more.

Setting a Specific TTL for a STOMP Connection

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add the connectionTtl parameter to URI of the acceptor used for STOMP connections, as in the example below.
<acceptors>
  <acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;connectionTtl=20000</acceptor>
  ...
</acceptors>

In the example above, any stomp connection that is created using the acceptor will have its TTL set to 20 seconds.

Note

Version 1.0 of the STOMP protocol does not contain any heartbeat frame. It is therefore the user’s responsibility to make sure data is sent within connection-ttl or the server will assume the client is dead and clean up server side resources. With version 1.1, users can use heart-beats to maintain the life cycle of stomp connections.

Overriding the Broker’s Default Time to Live (TTL)

As noted the default TTL for a STOMP connection is 1 minute. You can override this value by adding the connection-ttl-override attribute to the broker configuration.

Overriding the Default TTL

  1. Open the configuration file BROKER_INSTANCE_DIR/etc/broker.xml
  2. Add the connection-ttl-override attribute and provide a value in milliseconds for the new default. It belongs inside the <core> stanza, as below.
<configuration ...>
  ...
  <core ...>
    ...
    <connection-ttl-override>30000</connection-ttl-override>
    ...
  </core>
<configuration>

In the example above the default Time to Live (TTL) for a STOMP connection is now 30 seconds, 30000 milliseconds.

7.5.5. Sending and Consuming Stomp Messages from JMS

Stomp is mainly a text-orientated protocol. To make it simpler to interoperate with JMS, the Stomp implementation checks for presence of the content-length header to decide how to map a Stomp message to JMS.

If you want a STOMP message to map to a …​The message should…​.

JMS TextMessage

Not include a content-length header.

JMS BytesMessage

Include a content-length header.

The same logic applies when mapping a JMS message to Stomp. A Stomp client can check the presence of the content-length header to determine the type of the message body (String or bytes).

See the STOMP specification for more information on message headers.

7.5.6. Mapping STOMP Destinations to AMQ Broker Addresses and Queues

When sending messages and subscribing, STOMP clients typically include a destination header. Destination names are string values that are mapped to a destination on the server. In AMQ Broker, these destinations are mapped to addresses and queues. See the STOMP specification for more information about the destination frame.

Take for example a Stomp client that sends the following message (headers and body included):

SEND
destination:/my/stomp/queue

hello queue a
^@

In this case, the broker will forward the message to any queues associated with the address /my/stomp/queue.

For example, when a Stomp client sends a message (using a SEND frame), the specified destination is mapped to an address.

It works the same way when the client sends a 'SUBSCRIBE' or 'UNSUBSCRIBE' frame, but in this case AMQ Broker will map the destination to a queue.

SUBSCRIBE
destination: /other/stomp/queue
ack: client

^@

In the preceding example, the broker will map the destination to the queue /other/stomp/queue.