Configure distributed queuing to send messages to MQTT clients

IBM® MQ applications can send MQTT v3 clients messages by publishing to subscription created by a client, or by sending a message directly. Whichever method is used, the message is placed on SYSTEM.MQTT.TRANSMIT.QUEUE, and sent to the client by the telemetry (MQXR) service. There are a number of ways to place a message on SYSTEM.MQTT.TRANSMIT.QUEUE.

Publishing a message in response to an MQTT client subscription

The telemetry (MQXR) service creates a subscription on behalf of the MQTT client. The client is the destination for any publications that match the subscription sent by the client. The telemetry services forwards matching publications back to the client.

An MQTT client is connected to IBM MQ as a queue manager, with its queue manager name set to its ClientIdentifier. The destination for publications to be sent to the client is a transmission queue, SYSTEM.MQTT.TRANSMIT.QUEUE. The telemetry service forwards messages on SYSTEM.MQTT.TRANSMIT.QUEUE to MQTT clients, using the target queue manager name as the key to a specific client.

The telemetry (MQXR) service opens the transmission queue using ClientIdentifier as the queue manager name. The telemetry (MQXR) service passes the object handle of the queue to the MQSUB call, to forward publications that match the client subscription. In the object name resolution, the ClientIdentifier is created as the remote queue manager name, and the transmission queue must resolve to SYSTEM.MQTT.TRANSMIT.QUEUE. Using standard IBM MQ object name resolution, ClientIdentifier is resolved as follows; see Table 1.
  1. ClientIdentifier matches nothing.
    • ClientIdentifier is a remote queue manager name. It does not match the local queue manager name, a queue manager alias, or a transmission queue name.
    • The queue name is not defined. Currently, the telemetry (MQXR) service sets SYSTEM.MQTT.PUBLICATION.QUEUE as the name of the queue. An MQTT v3 client does not support queues, so the resolved queue name is ignored by the client.
    • The local queue manager property, Default transmission queue, name must be set to SYSTEM.MQTT.TRANSMIT.QUEUE, so that the publication is put on SYSTEM.MQTT.TRANSMIT.QUEUE to be sent to the client.
  2. ClientIdentifier matches a queue manager alias named ClientIdentifier.
    • ClientIdentifier is a remote queue manager name. It matches the name of a queue manager alias.
    • The queue manager alias must be defined with ClientIdentifier as the remote queue manager name.
    • By setting the transmission queue name in the queue manager alias definition it is not necessary for the default transmission to be set to SYSTEM.MQTT.TRANSMIT.QUEUE.
Table 1. Name resolution of an MQTT queue manager alias
  Input Output
ClientIdentifier Queue manager name Queue name Queue manager name Queue name Transmission queue
Matches nothing ClientIdentifier undefined ClientIdentifier undefined Default transmission queue.
SYSTEM.MQTT.
TRANSMIT.QUEUE

Matches a queue manager alias named ClientIdentifier ClientIdentifier undefined ClientIdentifier undefined
SYSTEM.MQTT.
TRANSMIT.QUEUE

For further information about name resolution, see Name resolution.

Any IBM MQ program can publish to the same topic. The publication is sent to its subscribers, including MQTT v3 clients that have a subscription to the topic.

If an administrative topic is created in a cluster, with the attribute CLUSTER(clusterName), any application in the cluster can publish to the client; for example:

Figure 1. Defining a cluster topic on Windows

echo DEFINE TOPIC('MQTTExamples') TOPICSTR('MQTT Examples') CLUSTER(MQTT) REPLACE | runmqsc qMgr
Note: Do not give SYSTEM.MQTT.TRANSMIT.QUEUE a cluster attribute.

MQTT client subscribers and publishers can connect to different queue managers. The subscribers and publishers can be part of the same cluster, or connected by a publish/subscribe hierarchy. The publication is delivered from the publisher to the subscriber using IBM MQ.

Sending a message to a client directly

An alternative to a client creating a subscription and receiving a publication that matches the subscription topic, send a message to an MQTT v3 client directly. MQTT V3 client applications cannot send messages directly, but other application, such as IBM MQ applications, can.

The IBM MQ application must know the ClientIdentifier of the MQTT v3 client. Because MQTT v3 clients do not have queues, the target queue name is passed to the MQTT v3 application client messageArrived method as a topic name. For example, in an MQI program, create an object descriptor with the client as the ObjectQmgrName:

Figure 2. MQI Object descriptor to send a message to an MQTT v3 client destination

MQOD.ObjectQmgrName = ClientIdentifier ;
MQOD.ObjectName = name ;

If the application is written using JMS, create a point-to-point destination; for example:

Figure 3. JMS destination to send a message to an MQTT v3 client

javax.jms.Destination jmsDestination =
(javax.jms.Destination)jmsFactory.createQueue
("queue://ClientIdentifier/name");
To send an unsolicited message to an MQTT client use a remote queue definition. The remote queue manager name must resolvedto the ClientIdentifier of the client. The transmission queue must resolve to SYSTEM.MQTT.TRANSMIT.QUEUE ; see Table 2. The remote queue name can be anything. The client receives it as a topic string.
Table 2. Name resolution of an MQTT client remote queue definition
Input Output
Queue name Queue manager name Queue name Queue manager name Transmission queue
Name of remote queue definition Blank or local queue manager name Remote queue name used as a topic string ClientIdentifier
SYSTEM.MQTT.
TRANSMIT.QUEUE

If the client is connected, the message is sent directly to the MQTT client, which calls the messageArrived method; see messageArrived method.

If the client has disconnected with a persistent session, the message is stored in SYSTEM.MQTT.TRANSMIT.QUEUE ; see MQTT stateless and stateful sessions. It is forwarded to the client when the client reconnects to the session again.

If you send a non-persistent message it is sent to the client with "at most once" quality of service, QoS=0. If you send a persistent message directly to a client, by default, it is sent with "exactly once" quality of service, QoS=2. As the client might not have a persistence mechanism, the client can reduce the quality of service it accepts for messages sent directly. To reduce the quality of service for messages sent directly to a client, make a subscription to the topic DEFAULT.QoS. Specify the maximum quality of service the client can support.