Skip to content

MQTT Swiftlet

Overview

The MQTT Swiftlet provides MQTT 3.1.1 protocol support for SwiftMQ routers, enabling MQTT clients to connect, publish, and subscribe to topics using the standard protocol. It manages MQTT connections, sessions (including persistent sessions), topic subscriptions, message delivery, and protocol-specific features such as retained messages and QoS handling. The Swiftlet integrates MQTT messaging seamlessly with the SwiftMQ topic and queue infrastructure, translating MQTT topics to SwiftMQ topic names and ensuring reliable delivery and session management.

Features

MQTT Protocol Support (3.1.1)

The Swiftlet implements the MQTT 3.1.1 protocol, supporting all standard message types including CONNECT, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, PINGREQ, PINGRESP, and DISCONNECT. It handles the full MQTT connection lifecycle, including authentication, session establishment, keepalive, and protocol error handling. MQTT topics are translated to SwiftMQ topic names by replacing slashes (/) with dots ('.'). Wildcards in topic filters ('#', '+') are translated to the SwiftMQ % wildcard, with additional validation to ensure compliance with both MQTT and SwiftMQ topic filter rules.

Topic Name Translation

MQTT topic names are mapped to SwiftMQ topic names by replacing / with '.'. Wildcards in topic filters ('#', '+') are mapped to %. The Swiftlet enforces that wildcards are not allowed at the root node and that system topics (starting with $) are not supported.

QoS Handling

All MQTT QoS levels (0, 1, 2) are supported. The Swiftlet manages the full publish/subscribe flow, including message acknowledgments and retransmissions as required by the protocol.

Retained Messages

The Swiftlet implements retained message support as per MQTT specification. Retained messages are stored in-memory and delivered to new subscribers as appropriate. A retained message with a zero-length payload will remove the retained message for the topic.

Connection and Listener Management

The Swiftlet allows configuration of one or more TCP listeners for MQTT clients, each with its own port, bind address, connection template, and optional host access restrictions. Connection templates define socket and buffer parameters, maximum message size, and other network-level properties. Each listener can restrict access to specific hosts or networks using host access lists. The Swiftlet enforces a configurable maximum number of concurrent connections per listener.

Connection Templates

Connection templates define socket factory, TCP options (such as TCP_NODELAY), buffer sizes, idle timeouts, and maximum message size. These templates can be referenced by listeners to standardize connection properties.

Host Access Lists

Each listener can specify a host access list to restrict inbound connections to specific IP addresses or subnets. Host access entries are predicates (typically IP addresses or patterns) that are checked for each incoming connection.

Configuration Example:

<swiftlet name="sys$mqtt">
  <listeners>
    <listener name="mqtt-default" port="1883" max-connections="100" connection-template="default">
      <host-access-list>
        <host-access-entry name="192.168.1.%"/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Session and Subscription Management

The Swiftlet manages both transient and persistent MQTT sessions. Persistent sessions are stored in the internal queue sys$mqtt_sessionstore and survive router restarts. Each session tracks its subscriptions, QoS, and message delivery state. The Swiftlet enforces a session timeout, after which unused persistent sessions are automatically deleted. Subscriptions are mapped to SwiftMQ topic subscriptions, and durable subscriptions are managed for persistent sessions.

Persistent Sessions

When a client connects with cleanSession=false, a persistent session is created or resumed. All subscriptions and undelivered messages are retained for the client. Persistent sessions are stored in the sys$mqtt_sessionstore queue using a JSON-encoded MapMessage format.

Session Timeout

A configurable session timeout (in hours) determines how long unused persistent sessions are kept. Sessions that are not associated with an active connection and have exceeded the timeout are automatically removed.

Subscription Management

Subscriptions are tracked per session. For persistent sessions, durable subscriptions are created and managed. Unsubscribing removes the subscription and, for persistent sessions, updates the session store.

Configuration Example:

<swiftlet name="sys$mqtt" session-timeout="72"/>

Live Usage and Statistics

The Swiftlet provides detailed live usage information for MQTT connections and sessions. For each active connection, statistics such as messages sent/received per second, total messages, client ID, username, and protocol level are tracked. For each session (including persistent sessions), the associated subscriptions and their QoS are displayed. These statistics are updated periodically based on the collect-interval setting.

Collect Interval

The collect-interval property determines how frequently message rate statistics (messages per second) are updated for connections and subscriptions.

Configuration Example:

<swiftlet name="sys$mqtt" collect-interval="5000"/>

Internal Queue Naming

  • sys$mqtt_sessionstore — Internal queue used to persist MQTT session state for persistent sessions.

Configuration Guide

Restrict MQTT Listener to a Specific Network and Limit Connections

Use this scenario to restrict an MQTT listener to accept connections only from a specific subnet and to limit the number of concurrent client connections.

  1. Define a listener with the desired port and connection template.
  2. Set the max-connections attribute to the desired limit.
  3. Add host-access-list entries for allowed subnets or IP addresses.
<swiftlet name="sys$mqtt">
  <listeners>
    <listener name="mqtt-secure" port="1883" max-connections="50" connection-template="default">
      <host-access-list>
        <host-access-entry name="10.0.0.%"/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Change Session Timeout for Persistent Sessions

Adjust the session-timeout to control how long unused persistent MQTT sessions are retained before automatic removal.

  1. Set the session-timeout attribute on the sys$mqtt Swiftlet to the desired number of hours.
<swiftlet name="sys$mqtt" session-timeout="24"/>

Configuration Reference

The top-level entity in routerconfig.xml is <swiftlet name="sys$mqtt">.

<swiftlet name="sys$mqtt"> Properties

These properties are attributes of the <swiftlet name="sys$mqtt"> entity.

Parameter Type Default Mandatory Reboot Required Description
collect-interval Long 1000 No No Collect Interval Messages/Sec
session-timeout Long 168 No No Time in hours after which a unused Session is deleted
<swiftlet name="sys$mqtt" collect-interval="1000" session-timeout="168"/>

<declarations> Entity

Declarations Section

This is a fixed child entity of <swiftlet name="sys$mqtt">.

<swiftlet name="sys$mqtt">
  <declarations/>
</swiftlet>

<connection-templates> in <declarations>

Templates for Connections

Each <connection-template> entry is identified by its name attribute (the Connection Template).

Parameter Type Default Mandatory Reboot Required Description
socketfactory-class String com.swiftmq.net.PlainSocketFactory No No Socketfactory Class
use-tcp-no-delay Boolean true No No Use Tcp No Delay
idle-timeout Long 90000 No No Inactivity timeout (ms) after which a Connection is disconnected
max-message-size Integer 10485760 No No Maximum Message Size (range: 0–2147483647)
reject-disconnect-delay Long 5000 No No Time (ms) after which a rejected Connection is closed (min: 1000)
router-input-buffer-size Integer 131072 No No Router Network Input Buffer Size (min: 1024)
router-input-extend-size Integer 65536 No No Router Network Input Extend Size (min: 1024)
router-output-buffer-size Integer 131072 No No Router Network Output Buffer Size (min: 1024)
router-output-extend-size Integer 65536 No No Router Network Output Extend Size (min: 1024)
<swiftlet name="sys$mqtt">
  <declarations>
    <connection-templates>
      <connection-template name="..."/>
    </connection-templates>
  </declarations>
</swiftlet>

<listeners> in <swiftlet name="sys$mqtt">

Listener Definitions

Each <listener> entry is identified by its name attribute (the Listener).

Parameter Type Default Mandatory Reboot Required Description
bindaddress String No No Listener Bind IP Address
port Integer 1883 Yes No Listener Port
max-connections Integer -1 Yes No Maximum Connections for Listener
connection-template String default Yes No Connection Template to use
<swiftlet name="sys$mqtt">
  <listeners>
    <listener name="..." port="..." max-connections="..." connection-template="..."/>
  </listeners>
</swiftlet>

<host-access-list> in <listeners>

Host Access List

Each <host-access-entry> entry is identified by its name attribute (the Host Access Entry).

<swiftlet name="sys$mqtt">
  <listeners>
    <listener name="...">
      <host-access-list>
        <host-access-entry name="..."/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Changelog

13.2.0 (2025-11-03)

  • SessionStore: migrated from XStream to JSON