MQTT User Properties sind Key/Value-String-Paare, die Sie an eine MQTT-5-Nachricht anhängen, ähnlich wie HTTP-Header. Damit senden Sie Metadaten wie eine Trace-ID, eine Schema-Version oder die Einheit eines Messwerts, ohne das Payload-Format zu ändern, das Ihre Konsumenten bereits parsen. In diesem Artikel erfahren Sie, wie sich User Properties verhalten, wo sie wirklich helfen und wie Sie sie in Python, Node.js und auf der Kommandozeile publizieren und lesen.
Was MQTT User Properties sind
MQTT 3.1.1 hatte keinen Platz für Metadaten. Alles außer Topic und Payload musste in den Payload selbst gequetscht oder im Topic-Namen kodiert werden. MQTT 5 führte Properties für die meisten Pakete ein, und die User Property ist diejenige, die für Anwendungen offen gelassen wurde.
Die wichtigsten Fakten zu User Properties:
- Jede Property ist ein Paar aus UTF-8-Strings: ein Name und ein Wert.
- Eine Nachricht kann beliebig viele davon tragen, und derselbe Name darf mehrfach vorkommen.
- Die Reihenfolge bleibt erhalten. Der Broker leitet sie in der Reihenfolge weiter, in der sie gesendet wurden.
- Bei PUBLISH-Paketen gibt der Broker sie unverändert an Subscriber weiter.
- Sie zählen zur Paketgröße und damit zu jedem Limit für die Nachrichtengröße.
- Sie können auch in CONNECT, SUBSCRIBE, DISCONNECT und anderen Paketen vorkommen, doch Anwendungen nutzen sie überwiegend in PUBLISH.
Da der Broker sie nicht interpretiert, sind User Properties eine reine Vereinbarung zwischen Ihren Publishern und Subscribern. Sie sind eine von mehreren MQTT-5-Funktionen, die das Protokoll für größere Systeme angenehmer machen.
Typische Einsatzfälle für MQTT User Properties
| Einsatzfall | Beispiel-Property | Warum nicht im Payload |
|---|---|---|
| Distributed Tracing | traceparent=00-4bf9...-01 |
Tracing ist ein Querschnittsthema; Payload-Schemas sollten sich dafür nicht ändern |
| Schema-Versionierung | schema=telemetry.v3 |
Konsumenten wählen vor dem Dekodieren einen Parser |
| Inhaltsmetadaten | unit=celsius, encoding=gzip |
Beschreibt, wie der Payload zu lesen ist |
| Quellenkennung | source=gateway-12, fw=2.4.1 |
Hilfreich beim Debuggen, ohne die Daten anzufassen |
| Routing-Hinweise | tenant=plant-a |
Middleware kann filtern, ohne zu parsen |
| Testmarkierungen | synthetic=true |
Konsumenten können Testtraffic verwerfen |
Der rote Faden: Informationen über die Nachricht, nicht der Messwert selbst. Braucht ein Dashboard einen Wert, um ein Diagramm zu zeichnen, gehört er in den Payload. Sagt ein Wert der Software, wie sie die Nachricht behandeln soll, passt eine User Property gut.
Bei binären Payloads wie Protobuf sind User Properties besonders praktisch, weil Sie Metadaten ergänzen können, ohne die .proto-Datei zu ändern. Den entsprechenden Vergleich finden Sie unter MQTT-Payload-Formate.
User Properties von der Kommandozeile senden
Die Mosquitto-Clients unterstützen User Properties, wenn Sie MQTT 5 wählen. Wir nutzen den öffentlichen MQTT-Broker unter broker.connectmq.com mit einem eindeutigen Topic-Präfix; er ist für Tests gedacht, nicht für Produktionsdaten.
Abonnieren Sie zuerst. Der Formatbezeichner %P gibt User Properties aus:
mosquitto_sub -V mqttv5 -h broker.connectmq.com -p 1883 -i up-sub-w2c5 \
-t 'connectmq/demo/w2c5/#' -F '%t %p | props: %P'
Publizieren Sie dann mit zwei Properties:
mosquitto_pub -V mqttv5 -h broker.connectmq.com -p 1883 -i up-pub-w2c5 \
-t connectmq/demo/w2c5/line1/temp -m '21.7' \
-D publish user-property unit celsius \
-D publish user-property schema temp.v1
Der Subscriber gibt Topic, Payload und unit:celsius schema:temp.v1 aus. Publizieren Sie denselben Befehl mit -V mqttv311, erhält der Subscriber zwar weiterhin den Payload, aber keine Properties, weil MQTT 3.1.1 sie nicht transportieren kann.
User Properties in Python publizieren und lesen
In paho-mqtt 2.x sind User Properties eine Liste von Tupeln an einem Properties-Objekt. Eine Liste statt eines Dicts, weil Namen sich wiederholen dürfen:
import time
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
BROKER = "broker.connectmq.com"
TOPIC = "connectmq/demo/w2c5/line1/pressure"
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(TOPIC, qos=1)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
props = Properties(PacketTypes.PUBLISH)
props.UserProperty = [
("trace-id", uuid.uuid4().hex),
("unit", "bar"),
("source", "gateway-12"),
]
client.publish(TOPIC, "2.31", qos=1, properties=props)
def on_message(client, userdata, msg):
user_props = dict(getattr(msg.properties, "UserProperty", []))
print(msg.topic, msg.payload.decode(), user_props)
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id=f"up-py-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=30)
client.loop_start()
time.sleep(3)
client.loop_stop()
client.disconnect()
Die Umwandlung in ein Dict ist bequem, aber nur dann sinnvoll, wenn Ihre Namen garantiert eindeutig sind. Erlauben Sie wiederholte Namen, behalten Sie die Liste.
User Properties in Node.js
MQTT.js v5 stellt User Properties als einfaches Objekt in properties.userProperties bereit. Ein Wert kann ein String oder bei wiederholten Namen ein Array von Strings sein:
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId: "up-js-" + Math.random().toString(16).slice(2, 10),
protocolVersion: 5,
});
const topic = "connectmq/demo/w2c5/line1/flow";
client.on("connect", () => {
client.subscribe(topic, { qos: 1 }, () => {
client.publish(topic, "12.4", {
qos: 1,
properties: {
userProperties: { unit: "m3/h", tag: ["calibrated", "line1"] },
},
});
});
});
client.on("message", (t, payload, packet) => {
console.log(t, payload.toString(), packet.properties?.userProperties);
client.end();
});
User Properties vs. Topic-Ebenen vs. Payload-Felder
Es gibt drei Orte, an denen Sie eine Information in einer MQTT-Nachricht unterbringen können, und jeder hat andere Kosten:
| Ort | Geeignet für | Sichtbar für | Kosten |
|---|---|---|---|
| Topic-Ebene | Routing und Filtern von Subscriptions (Standort, Linie, Gerät) | Broker, jeden Subscriber, Wildcards | Teil jedes Topic-Strings; Änderungen brechen Subscriptions |
| User Property | Verarbeitungshinweise, Tracing, Schema-Version | Nur Subscriber; der Broker ignoriert sie | Bytes pro Nachricht; gehen bei MQTT-3.1.1-Zwischenstationen verloren |
| Payload-Feld | Fachdaten, die Konsumenten speichern oder anzeigen | Subscriber nach dem Dekodieren | Hinzufügen erfordert Schema-Änderungen |
Eine nützliche Faustregel: Muss ein Subscriber danach filtern, nutzen Sie das Topic. Muss ein Subscriber vor dem Dekodieren entscheiden, wie er die Nachricht verarbeitet, nutzen Sie eine User Property. Speichert oder zeigt der Subscriber den Wert, gehört er in den Payload.
Ein unit-Wert könnte beispielsweise sowohl in eine Property als auch in den Payload. Speichert jeder Konsument die Einheit zusammen mit dem Wert, legen Sie sie in den Payload, damit sie das Schreiben in eine Datenbank übersteht. Ist die Einheit pro Topic fest und prüft sie nur eine Validierungsschicht, ist eine Property sauberer. Beachten Sie, dass Wildcard-Subscriptions nur auf Topic-Ebenen filtern: Ein Subscriber kann den Broker nicht anhand einer User Property um „Nachrichten mit tenant gleich plant-a“ bitten.
In einem Unified Namespace (UNS) ergibt sich daraus eine klare Aufteilung: Die ISA-95-Hierarchie aus Unternehmen, Werk, Bereich, Linie und Zelle gehört ins Topic, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/temperatur, denn danach filtern MES, SCADA und Dashboards. Herkunftsangaben wie die OPC-UA-Quelle eines Werts, die Firmware-Version eines Gateways oder eine Schema-Version passen dagegen gut in User Properties, weil sie die Verarbeitung steuern, ohne den Namespace aufzublähen.
Gestaltungsrichtlinien
- Definieren Sie ein kleines Vokabular. Einigen Sie sich teamübergreifend auf eine Handvoll Namen und dokumentieren Sie sie. Ad-hoc-Properties werden schnell zu Rauschen.
- Halten Sie sie kurz. Properties reisen mit jeder Nachricht. Zehn lange Header an einem 20-Byte-Sensorwert können dessen Größe vervielfachen.
- Legen Sie keine Geheimnisse hinein. Sie sind für jeden, der abonnieren kann, genauso sichtbar wie der Payload.
- Machen Sie kritische Daten nicht von ihnen abhängig, wenn einige Konsumenten noch MQTT 3.1.1 nutzen. Diese Konsumenten verlieren sie stillschweigend.
- Nutzen Sie Standardformate, wo es sie gibt, etwa W3C
traceparentfür Tracing, damit Tools sie verstehen. - Bevorzugen Sie für den Payload-Typ den Content Type. MQTT 5 hat eine eigene Content-Type-Property und einen Payload Format Indicator; verwenden Sie diese statt einer eigenen
content-type-User-Property.
Fehlersuche bei User Properties
Beim Subscriber fehlen die Properties. Subscriber oder Publisher haben sich mit MQTT 3.1.1 verbunden. Beide Verbindungen müssen MQTT 5 nutzen.
Nachrichten werden als zu groß abgelehnt. Properties zählen zur Paketgröße. Kürzen Sie sie bei einem größenbeschränkten Plan oder Broker. Unser Artikel zum MQTT-Limit für die Nachrichtengröße erklärt, wie das Limit durchgesetzt wird.
Werte erscheinen unerwartet als Arrays. In MQTT.js wird ein wiederholter Name zu einem Array. Behandeln Sie beide Formen oder vermeiden Sie wiederholte Namen.
Weitergeleitete oder neu publizierte Nachrichten verlieren Properties. Jede Komponente, die eine Nachricht liest und erneut publiziert, muss die Properties explizit kopieren; viele einfache Skripte tun das nicht.
User Properties auf ConnectMQ
ConnectMQ leitet MQTT-5-User-Properties wie jeder standardkonforme Broker unverändert zwischen Publishern und Subscribern weiter. Denken Sie daran, dass sie zur Nachrichtengröße zählen: 256 KB im kostenlosen Serverless-Plan, 1 MB im kostenpflichtigen Serverless-Plan und 64 KB auf dem öffentlichen MQTT-Broker. Um Ihre Metadaten in der Praxis zu sehen, abonnieren Sie mit dem obigen Mosquitto-Befehl oder mit Ihrem eigenen Client auf Ihrem Broker, mit den Zugangsdaten aus dem Portal. Wenn Sie die Infrastruktur noch auswählen, erklärt unsere Übersicht zum verwalteten MQTT-Broker, was Sie erhalten, und das MQTT-Tutorial behandelt die Grundlagen.
Starten Sie mit ConnectMQ
Registrieren Sie sich unter app.connectmq.com und erstellen Sie einen Broker im kostenlosen Serverless-Plan, ganz ohne Kreditkarte. Verbinden Sie sich mit MQTT 5, fügen Sie Ihren Nachrichten eine Trace-ID hinzu und verfolgen Sie sie auf Ihrem eigenen Cloud-MQTT-Broker vom Gerät bis zum Dashboard.
Häufig gestellte Fragen
Dürfen sich Namen von User Properties wiederholen?
Ja. MQTT 5 erlaubt denselben Namen mehrfach, und der Broker erhält die Reihenfolge. Speichern Sie sie als Liste, wenn Sie sich darauf verlassen.
Verändert der Broker User Properties?
Bei PUBLISH-Paketen leitet der Broker sie unverändert an Subscriber weiter. Er interpretiert oder filtert sie nicht.
Gibt es User Properties in MQTT 3.1.1?
Nein. Sie sind eine MQTT-5-Funktion. Ein 3.1.1-Subscriber erhält den Payload ohne jegliche Properties.
Zählen User Properties zur Nachrichtengröße?
Ja. Sie sind Teil des Pakets und zählen daher zur maximalen Paketgröße des Brokers.



