MQTT payload formatını seçmek, her IoT projesindeki ilk tasarım kararlarından biridir ve sonradan değiştirmesi en zor olanlardandır. MQTT payload'ı opak baytlar olarak ele alır; bu yüzden JSON, Protobuf, CBOR veya özel bir binary düzen iletim hattında sorunsuz çalışır. Bu karşılaştırma, en yaygın üç kodlamanın boyut, şema yönetimi ve araç desteği açısından nasıl farklılaştığını aynı sensör mesajının bayt sayılarıyla gösterir; böylece cihazlarınız için doğru olanı seçebilirsiniz.
MQTT Payload'dan Bağımsızdır
Bir MQTT PUBLISH paketi bir topic, bazı bayraklar, isteğe bağlı MQTT 5 property'leri ve protokol sınırına göre 256 MB'a kadar bir payload içerir (broker'lar pratikte çok daha düşük sınırlar uygular). MQTT broker payload'ın içine asla bakmaz. Bu size özgürlük verir; ancak aynı zamanda iki ekibin aynı topic'e uyumsuz formatlar publish etmesini hiçbir şeyin engellemediği anlamına gelir.
MQTT 5, yardımcı olan iki property ekler:
- Payload Format Indicator: 0 belirtilmemiş baytlar, 1 ise UTF-8 metin anlamına gelir.
- Content Type: serbest biçimli bir string; genellikle
application/jsonveyaapplication/x-protobufgibi bir MIME türü.
Bunları ayarlamak birkaç bayta mal olur ve genel amaçlı araçların, log sistemlerinin ve tüketicilerin mesajlarınızı doğru işlemesini sağlar.
Örnek Mesaj
Adil bir karşılaştırma için aynı pompa okumasını her formatta kodluyoruz:
{"deviceId":"pump-07","ts":1760600000,"temp":21.5,"pressure":2.31,"rpm":1480,"running":true}
Altı alan: bir string kimlik, bir Unix zaman damgası, iki ondalık ölçüm, bir tamsayı ve bir boolean. Bu, endüstriyel ve bina telemetrisi için gerçekçi bir yapıdır.
Boyut Karşılaştırması
Aşağıdaki bayt sayıları, bu mesaj için her formatın kodlama kurallarına göre hesaplanmıştır:
| Kodlama | Bayt | Notlar |
|---|---|---|
| JSON, girintili (2 boşluk) | 117 | İnsan dostu, iletimde israf |
| JSON, kompakt | 92 | Yaygın varsayılan |
| JSON, kısa anahtarlarla kompakt | 65 | {"d":"pump-07","t":1760600000,"tp":21.5,"p":2.31,"r":1480,"on":1} |
| CBOR, 64 bit float | 74 | JSON ile aynı anahtarlar, binary değerler |
| CBOR, 32 bit float | 64 | pressure üzerinde hassasiyet ödünü |
Protobuf, float olarak float'lar |
30 | Adlar yerine alan numaraları |
Birkaç gözlem:
- JSON boyutunun büyük kısmı anahtar adları ve sayıların metin hali. Format değiştirmeden önce anahtarları kısaltmak bile çok yol aldırır.
- CBOR kendini tanımlayan map yapısını korur; bu yüzden anahtar adları yine her mesajla birlikte gider. Tasarrufu binary sayılar ve boolean'lardan gelir.
- Protobuf küçüktür, çünkü alan adları mesajda değil bir şema dosyasında yaşar. Alıcının bu şemaya sahip olması gerekir.
Payload'ın üzerine bir de MQTT başlığı ve topic eklendiğini unutmayın. site/plant1/line1/pump-07/telemetry gibi bir topic 35 bayttır; bu da Protobuf payload'ının tamamından büyüktür. Bant genişliği gerçekten önemliyse yalnızca kodlamaya değil, topic uzunluğuna ve MQTT 5 topic alias'larına da bakın. Baytların nereye gittiğine daha geniş bir bakış için MQTT bant genişliği kullanımı yazısına göz atın.
JSON: Haklı Nedenlerle Varsayılan
JSON boyut dışında her konuda kazanır:
- Her MQTT istemcisinde, log dosyasında veya terminalde okunabilir.
- Mikrodenetleyicilerde ArduinoJson dahil her dil ve platformun bir ayrıştırıcısı vardır.
- Node-RED, Telegraf, Home Assistant ve çoğu dashboard onu yapılandırma gerektirmeden kabul eder.
- Bir alan eklemek eski tüketicileri nadiren bozar.
Zayıf yönleri: şema zorunluluğu yoktur, sayı türleri belirsizdir (1 bir boolean mı, tamsayı mı, float mı?) ve çok küçük mikrodenetleyicilerde ayrıştırma maliyeti vardır. Şebekeden beslenen ve Wi-Fi veya Ethernet kullanan cihazların olduğu çoğu proje için bu ödünler kabul edilebilir.
Protobuf: Şemayla Birlikte En Küçük
Protocol Buffers her alanı bir alan numarası ve kompakt bir değer olarak kodlar. Mesajımızın şeması:
syntax = "proto3";
message PumpReading {
string device_id = 1;
uint64 ts = 2;
float temp = 3;
float pressure = 4;
uint32 rpm = 5;
bool running = 6;
}
Güçlü yönleri: en küçük payload'lar, güçlü tür denetimi, birçok dilde üretilen kod ve şemaları geliştirmek için iyi tanımlanmış kurallar (yeni numaralarla alan ekleyin, eskilerini asla yeniden kullanmayın). Endüstriyel MQTT'de yaygın kullanılan Sparkplug B, tam da bu nedenlerle Protobuf üzerine kuruludur; bkz. MQTT Sparkplug B ve Unified Namespace.
Zayıf yönleri: şema olmadan okunamaz, bu yüzden hata ayıklamak için çözümleme araçları gerekir; şema dosyalarının her üretici ve tüketiciye dağıtılması ve sürümlenmesi gerekir; genel amaçlı entegrasyonlar bir çözümleme adımı olmadan veriyi kullanamaz.
CBOR: Binary JSON
CBOR (RFC 8949), JSON'un veri modelini (map'ler, diziler, string'ler ve sayılar) korur ama binary olarak kodlar. Şema gerektirmez; bu yüzden herhangi bir CBOR çözücü bir mesajı JSON benzeri bir yapıya geri dönüştürebilir.
Güçlü yönleri: JSON'dan küçüktür, kendini tanımlar, yerel binary bayt string'leri vardır (base64 gerekmez) ve CoAP gibi kısıtlı protokollerde popülerdir. Zayıf yönleri: anahtarları da kısaltmazsanız tasarruf orta düzeydedir, araç desteği JSON'a göre zayıftır ve float kodlaması kütüphaneler arasında farklılık gösterir; bu da baytları karşılaştırırken sizi şaşırtabilir.
Karar Kontrol Listesi
- Bu mesajları insanlar sık sık okuyacak mı? JSON'u tercih edin.
- Cihazlar ölçülü (kotalı) hücresel bağlantıda, LoRa backhaul'da veya uyduda mı? Protobuf'u ya da ilk adım olarak kısa anahtarlı kompakt JSON'u düşünün.
- Aynı veriyi birçok ekip ve dil mi tüketiyor? Protobuf şemaları kendini amorti eder; aksi halde belgelenmiş bir şemaya sahip JSON.
- Yapılandırılmış veri içinde binary blob'lara mı ihtiyacınız var? CBOR bunları yerel olarak işler.
- Hazır araçlarla mı entegre oluyorsunuz? JSON kullanın veya JSON'u yeniden publish eden bir çözümleme adımı planlayın.
- Endüstriyel birlikte çalışabilirlik mi gerekiyor? Kendi Protobuf şemanızı icat etmeden önce Sparkplug B'ye bakın.
Ne seçerseniz seçin, sürümleyin. Payload'da bir schema alanı, topic'te bir sürüm veya bir MQTT 5 user property işe yarar; önemli olan tüketicilerin formatları birbirinden ayırt edebilmesidir.
Python'da Content Type ile Publish Etmek
Bu paho-mqtt 2.x örneği, kompakt JSON okumasını MQTT 5 payload format indicator ve content type ayarlanmış şekilde herkese açık MQTT test broker'ına publish eder:
import json
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
reading = {"deviceId": "pump-07", "ts": 1760600000, "temp": 21.5,
"pressure": 2.31, "rpm": 1480, "running": True}
payload = json.dumps(reading, separators=(",", ":")).encode()
print("payload bytes:", len(payload)) # 92
props = Properties(PacketTypes.PUBLISH)
props.PayloadFormatIndicator = 1
props.ContentType = "application/json"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"fmt-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5)
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
client.publish("connectmq/demo/f6n1/pump-07/telemetry", payload,
qos=1, properties=props).wait_for_publish()
client.loop_stop()
client.disconnect()
separators=(",", ":") kısmına dikkat edin: Python'un varsayılan json.dumps çıktısı her virgül ve iki noktadan sonra bir boşluk ekler; bu da payload'ı tablodaki kompakt değerden büyük yapar.
Payload Tuzakları
- Tek bir topic'te formatları karıştırmak. Tüketiciler kafa karıştırıcı şekillerde bozulur. Bir topic, bir format.
- Kayan nokta sürprizleri. 32 bit float'lar 2.31'i tam olarak temsil edemez. Hassasiyete bilinçli karar verin veya ölçeklenmiş tamsayılar gönderin.
- Yerel saatle zaman damgaları. UTC Unix zamanı veya ofsetli ISO 8601 kullanın.
- Boyut sınırlarını aşmak. Çok sayıda okumayı tek mesajda toplamak broker'ın maksimum mesaj boyutuna takılabilir; bkz. MQTT mesaj boyutu sınırı.
ConnectMQ'da Payload Formatları
MQTT payload'ları opak baytlar olduğundan ConnectMQ her payload formatını taşır. Bunun yanı sıra ConnectMQ, Sparkplug B payload'larını (Protobuf veya JSON) çözümleyip okunabilir ISA-95 topic'lerine yeniden publish edebilir. Mesaj sınırları ücretsiz Serverless planında 256 KB, ücretli Serverless planında 1 MB'tır; bu, yukarıdaki tek okumalık kodlamaların her biri için fazlasıyla yeterlidir. Altyapıyı işletmek istemiyorsanız yönetilen bir MQTT broker payload sözleşmesine odaklanmanızı sağlar. Protokolün geri kalanını MQTT eğitimi ele alır.
ConnectMQ ile Başlayın
app.connectmq.com adresinde, kredi kartı gerekmeden Serverless planında ücretsiz bir broker oluşturun. Aynı okumayı JSON'da ve seçtiğiniz binary formatta publish edin ve ConnectMQ portalının tarayıcı içi istemcisinde yan yana karşılaştırın.
Sık Sorulan Sorular
En iyi MQTT payload formatı hangisi?
Tek bir en iyisi yoktur. JSON birlikte çalışabilirlik ve hata ayıklama için en güvenli varsayılandır; Protobuf ise bant genişliği kısıtlı olduğunda ve şemalar iyi yönetildiğinde en iyisidir.
Broker payload formatını doğrular mı?
Hayır. MQTT broker'ları payload'ları opak baytlar olarak ele alır. Doğrulama tüketicilerinizde gerçekleşir.
JSON payload'larını sıkıştırmalı mıyım?
Tek ve küçük okumalarda sıkıştırma çoğu zaman az tasarruf sağlar ve CPU harcar. Büyük, toplu mesajlarda daha çok işe yarar.
Tüketicilere bir mesajın hangi formatı kullandığını nasıl bildiririm?
MQTT 5'te Content Type property'sini ayarlayın. MQTT 3.1.1'de bir topic kuralı veya payload içinde bir sürüm alanı kullanın.



