MQTT Temelleri

MQTT'de Retained Mesaj Nasıl Silinir? (CLI, Python ve Web İstemcisi)

Eskimiş bir retained mesaj, her yeni subscriber'ı eski verilerle karşılamaya devam eder. MQTT'de retained bir mesajı boş bir retained publish ile komut satırından, Python'dan, JavaScript'ten ve bir tarayıcı istemcisinden nasıl sileceğinizi burada bulabilirsiniz.

MQTT retained mesaj silme işlemini göstermek için eskimiş bir değerin temizlendiği broker topic ağacı çizimi
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

MQTT'de retained mesaj silmek için bir broker yönetim aracına ihtiyacınız yoktur: aynı topic'e retain bayrağı ayarlı, sıfır uzunlukta bir payload publish edersiniz ve broker saklanan değeri bırakır. Bu rehber, bu tekniği komut satırından, Python'dan, JavaScript'ten ve bir tarayıcı istemcisinden göstermenin yanı sıra eskimiş retained topic'leri güvenle bulup toplu olarak temizlemeyi de anlatıyor.

Retained Mesajlar Neden Takılı Kalır?

Retained mesaj, bir broker'ın bir topic için sakladığı son mesajdır; böylece her yeni subscriber güncel değeri hemen alır. Bu, bir cihaz durumu, bir yapılandırma belgesi veya en son sensör okuması için tam istediğiniz şeydir. Bu özellikte yeniyseniz MQTT retained mesajlar rehberi mekanizmayı ayrıntılı olarak açıklar.

Sorun, saklanan değer artık doğru olmadığında başlar. Tipik durumlar:

  • Bir cihaz hizmetten çıkarıldı, ancak son online durumu dashboard'larda görünmeye devam ediyor.
  • Geliştirme sırasında retain bayrağıyla yapılan bir test publish'i artık bir üretim topic ağacını kirletiyor.
  • Bir yapılandırma topic'i yeniden adlandırıldı ve eskisi hâlâ yeni client'lara güncelliğini yitirmiş ayarlar gönderiyor.
  • Bir firmware hatası retain ile bozuk JSON publish etti ve yeniden bağlanan her subscriber bu yüzden çöküyor.

Broker retained değeri her yeni subscription'da yeniden oynattığı için sorun kendiliğinden asla geçmez. Saklanan değeri değiştirmeniz veya kaldırmanız gerekir.

MQTT'de Retained Mesaj Nasıl Silinir?

MQTT spesifikasyonu kuralı tek cümleyle tanımlar: RETAIN bayrağı 1 olarak ayarlanmış ve payload'ı sıfır uzunlukta olan bir PUBLISH paketi, o topic için varsa retained mesajı kaldırır ve broker yeni bir tane saklamaz. Boş mesaj mevcut subscriber'lara da iletilir; bu yüzden tüketicileriniz boş bir payload'ı JSON olarak ayrıştırmaya çalışmak yerine tolere etmelidir.

Pratikte birkaç ayrıntı önemlidir:

  1. Topic tam olarak eşleşmelidir. Retained mesajlar topic adı bazında saklanır. sensors/# adresine boş bir retained mesaj publish etmek hiçbir şey yapmaz, çünkü publish ettiğiniz topic adlarında wildcard'lara izin verilmez.
  2. Payload gerçekten boş olmalıdır. Tek bir boşluk, boş bir JSON nesnesi {} veya null string'i gerçek payload'lardır ve yeni değer olarak saklanır.
  3. QoS pek önemli değildir. Temizlik için QoS 0 yeterlidir, ancak QoS 1 broker'ın mesajı aldığına dair bir onay verir.
  4. O topic'te publish izniniz olmalıdır. Kimlik bilgileriniz oraya publish edemiyorsa, broker'a ve protokol sürümüne bağlı olarak silme işlemi reddedilir veya sessizce düşürülür.

mosquitto_pub ile Retained Mesajları Temizlemek

Mosquitto komut satırı araçları tek bir topic'i temizlemenin en hızlı yoludur. -r bayrağı retain'i ayarlar, -n ise null (sıfır uzunlukta) bir mesaj gönderir:

# Topic'te şu anda neyin retained olduğunu inceleyin
mosquitto_sub -h broker.connectmq.com -p 1883 -i inspect-7f3a \
  -t "connectmq/demo/7f3a/device42/status" -v -C 1 -W 5

# Retained mesajı silin
mosquitto_pub -h broker.connectmq.com -p 1883 -i cleanup-7f3a \
  -t "connectmq/demo/7f3a/device42/status" -r -n

# Doğrulayın: bu artık hiçbir şey yazdırmadan zaman aşımına uğramalı
mosquitto_sub -h broker.connectmq.com -p 1883 -i verify-7f3a \
  -t "connectmq/demo/7f3a/device42/status" -v -C 1 -W 5

-C 1 -W 5 kombinasyonu, mosquitto_sub'a bir mesajdan veya beş saniyeden sonra çıkmasını söyler; bu da onu hızlı bir "burada retained bir şey var mı?" yoklamasına dönüştürür. Örnekler, benzersiz bir önekle herkese açık MQTT test broker'ını kullanır; 7f3a değerini kendi rastgele ID'nizle değiştirin.

Özel bir broker'da kimlik bilgilerini ve TLS'i ekleyin:

mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID \
  -t "plant1/line2/press/status" -r -n -q 1

--remove-retained ile Toplu Temizlik

mosquitto_sub, alt ağaçların tamamı için kullanışlı bir seçeneğe sahiptir. --remove-retained ile aldığı her retained mesaj, o topic'e boş bir retained mesaj geri publish edilerek temizlenir. Yalnızca retained değerlere dokunması ve canlı trafiği yok sayması için bunu --retained-only ile birleştirin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i purge-7f3a \
  -t "connectmq/demo/7f3a/#" --retained-only --remove-retained -v -W 5

Önce inceleme komutunu çalıştırın, listeyi dikkatle okuyun ve ardından temizleyin. Paylaşılan bir ağaçta # gibi bir wildcard, niyet ettiğinizden çok daha fazlasını silebilir.

Python ile Retained Mesaj Silmek

Temizlik bir hizmetten çıkarma betiğinin parçasıysa paho-mqtt 2.x ile Python kullanışlıdır. payload=None vermek sıfır uzunlukta bir payload üretir:

import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
TOPIC = "connectmq/demo/7f3a/device42/status"

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    info = client.publish(TOPIC, payload=None, qos=1, retain=True)
    info.wait_for_publish(timeout=5)
    print("Retained message cleared on", TOPIC)
    client.disconnect()

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="cleanup-py-7f3a")
client.on_connect = on_connect
client.connect(BROKER, 1883, keepalive=30)
client.loop_forever()

Bir Alt Ağacın Tamamını Bulup Temizlemek

Bu sürüm bir wildcard ile subscribe olur, kısa bir süre içinde retained mesaj teslim eden her topic'i toplar ve ardından bunları tek tek temizler. Publish hızını sınırlar; bu, her client'ın saniyede 10 mesajla sınırlı olduğu herkese açık broker'da önemlidir.

import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
FILTER = "connectmq/demo/7f3a/#"
found = set()

def on_message(client, userdata, msg):
    if msg.retain and msg.payload:
        found.add(msg.topic)

def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(FILTER, qos=1)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="purge-py-7f3a")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=30)
client.loop_start()
time.sleep(3)  # retained mesajları topla

print(f"Found {len(found)} retained topics")
for topic in sorted(found):
    print("Clearing", topic)
    client.publish(topic, payload=None, qos=1, retain=True).wait_for_publish(5)
    time.sleep(0.15)  # client başına hız sınırının altında kal

client.loop_stop()
client.disconnect()

msg.retain kontrolüne dikkat edin. Broker'lar, yeni bir subscription nedeniyle teslim edilen mesajlarda retain bayrağını ayarlar; böylece bu süre içinde tesadüfen gelen canlı mesajlar saklanan değerlerle karıştırılmaz.

JavaScript'ten veya Tarayıcıdan Retained Mesaj Silmek

MQTT.js ile de aynı kural geçerlidir: retain: true ile boş bir string veya boş bir buffer.

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "cleanup-js-7f3a",
  protocolVersion: 5,
});

client.on("connect", () => {
  client.publish(
    "connectmq/demo/7f3a/device42/status",
    "",
    { qos: 1, retain: true },
    (err) => {
      console.log(err ? `Failed: ${err.message}` : "Retained message cleared");
      client.end();
    }
  );
});

Hiç kod yazmak istemiyorsanız ConnectMQ portalındaki tarayıcı içi MQTT istemcisi de işe yarar: broker'ınıza bağlanın, tam topic'i girin, payload alanını boş bırakın, retain'i etkinleştirin ve publish edin. Canlı topic gezgini, temizlikten önce ve sonra hangi topic'lerin hâlâ bir değer tuttuğunu görmenin iyi bir yoludur.

Bir Türlü Silinmeyen Retained Mesajda Sorun Giderme

Belirti Olası neden Çözüm
Eski değer saniyeler sonra yeniden görünüyor Bir cihaz veya servis onu hâlâ retain ile publish ediyor Publisher'ı bulun, retain bayrağını düzeltin, sonra tekrar temizleyin
Boş publish'ten sonra hiçbir şey değişmiyor Topic uyuşmazlığı (büyük/küçük harf, sondaki eğik çizgi, fazladan seviye) Tam topic'i bir -v subscription çıktısından kopyalayın
Temizlikten sonra subscriber'lar çöküyor Tüketiciler boş payload'ı ayrıştırıyor Mesaj işleyicide sıfır uzunluktaki mesajları atlayın
Değer kaldırılmıyor, değiştiriliyor Payload bir boşluk, {} veya null idi Yer tutucu bir string değil, -n veya payload=None kullanın
Temizlik testte çalışıyor, üretimde çalışmıyor Kimlik bilgilerinin o topic'te publish yetkisi yok Topic ağacının sahibi olan hesabı kullanın

İlk satır açık ara en yaygın olanıdır. "Geri gelen" retained bir değer neredeyse her zaman bir şey tarafından yeniden publish ediliyordur; bu çoğu zaman bir köprü betiği, bir Node-RED akışı veya her yeniden bağlantıda durumunu retain ile publish eden bir cihazdır.

Eskimiş Retained Verilerden Baştan Kaçının

Retained mesajları silmek bir temizlik işidir; onları iyi tasarlamak buna ne sıklıkla ihtiyaç duyduğunuzu azaltır.

  • MQTT 5 message expiry kullanın. Retained publish'lerde bir Message Expiry Interval ayarlayın; böylece broker onları belirli bir süre sonra atar. Message expiry interval rehberi makul değerleri ele alır.
  • Durumu Last Will ile eşleştirin. Retained bir online durumu, retained bir offline Last Will mesajıyla eşleştirilmelidir; böylece bir cihaz düştüğünde saklanan değer doğru kalır.
  • Retained topic'leri dar tutun. Akışları değil, durumu saklayın. Yüksek frekanslı telemetrinin nadiren retain'e ihtiyacı vardır ve daha az retained topic, temizlenecek daha az şey demektir.
  • Retained mesajları bir veritabanı gibi kullanmayın. Kalıcı geçmiş değil, kolaylık için en son değeri tutarlar. Saklamanız gereken her şeyi bir subscriber tarafından beslenen gerçek bir veritabanında tutun.
  • Hangi topic'lerin retained olduğunu belgeleyin. Topic adlandırma kurallarınızdaki kısa bir liste, biri wildcard subscription eklediğinde sürprizleri önler.

Retain bayrağının tam davranışı OASIS MQTT 5.0 standardında tanımlanmıştır; daha kapsamlı MQTT eğitimi ise retained mesajları QoS, oturumlar ve will'lerle birlikte bağlamına oturtur.

ConnectMQ'da Retained Topic'leri Yönetin

ConnectMQ hem MQTT 3.1.1 hem de 5.0'da retained mesajları destekler; bu yüzden yukarıdaki tüm teknikler değişiklik olmadan çalışır. Denemelerin ötesine geçiyorsanız, yönetilen bir MQTT broker size özel kimlik bilgileri, 8883 portunda TLS ve bu tür bakım işleri için tarayıcı içi istemci ile canlı topic gezgini olan bir portal sunar. Sunucuları kendiniz işletmeden bulutta MQTT broker çalıştırmak hakkında daha fazlasını okuyabilirsiniz.

app.connectmq.com adresinde, kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun; birkaç dakika içinde bir kullanıcı adı, parola ve client ID'ye sahip olursunuz.

Sık Sorulan Sorular

MQTT'de retained bir mesajı nasıl silerim?

Tam olarak aynı topic'e sıfır uzunlukta payload'a sahip ve retain bayrağı ayarlı bir mesaj publish edin. Mosquitto ile bu mosquitto_pub -t <topic> -r -n komutudur ve broker o topic için retained bir değer saklamayı bırakır.

Tüm retained mesajları bir wildcard ile silebilir miyim?

Tek bir publish ile hayır, çünkü topic adlarında wildcard'lara izin verilmez. Retained topic'leri keşfetmek için bir wildcard filtresiyle subscribe olun ve ardından her birini temizleyin ya da mosquitto_sub --retained-only --remove-retained kullanın.

Boş bir JSON nesnesi göndermek retained mesajı siler mi?

Hayır. {} iki baytlık bir payload'dır; bu yüzden broker onu yeni değer olarak saklar. Yalnızca gerçekten boş bir payload retained mesajı kaldırır.

Subscriber'lar boş mesajı alır mı?

Evet, mevcut subscriber'lar sıfır uzunluktaki mesajı diğer her publish gibi alır. Tüketicilerinizin boş payload'ları ayrıştırmaya çalışıp hata vermek yerine yok saydığından emin olun.

İlgili yazılar

MQTT'yi Kim İcat Etti? Petrol Boru Hatlarından IoT'ye Uzanan Tarih

MQTT, 1999'da IBM'den Andy Stanford-Clark ve Arcom'dan Arlen Nipper tarafından petrol boru hatlarını uydu üzerinden izlemek için icat edildi. Açık kaynağa, OASIS'e, ISO'ya ve bugünün yönetilen bulut broker'larına uzanan yolculuğunu izleyin.

7 dk okuma

MQTT Maksimum Mesaj Boyutu: Sınırlar ve Büyük Payload Stratejileri

MQTT teknik olarak 256 MB'lık bir paket taşıyabilir, ancak broker'lar, istemci kütüphaneleri ve cihazlar çok daha düşük sınırlar uygular. Gerçek sınırların nerede olduğunu, aşıldıklarında ne olduğunu ve büyük payload'ların nasıl gönderileceğini öğrenin.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.