Temeller

MQTT Retained Mesajlar: Nasıl Çalışır ve Nasıl Silinir?

MQTT retained mesajlar: retain bayrağı nasıl çalışır, ne zaman kullanılır, retained mesaj boş payload ile nasıl silinir ve MQTT 5 retain seçenekleri nelerdir?

Güncellendi · 6 dk okuma

Normalde bir MQTT broker’ı bir mesajı o anda abone olan client’lara iletir ve sonra unutur. Bir dakika sonra abone olan bir client, bir sonraki publish’e kadar hiçbir şey görmez. Retained mesajlar bu sorunu çözer: broker bir topic için son retained mesajı saklar ve her yeni subscriber’a hemen teslim eder; böylece subscriber’lar her zaman güncel durumla başlar.

Retained mesajlar nasıl çalışır?

Saklama tek bir bit ile kontrol edilir: PUBLISH paketindeki RETAIN bayrağı. Broker RETAIN=1 olan bir publish aldığında:

  1. Mesajı her zamanki gibi mevcut subscriber’lara teslim eder.
  2. Mesajı (topic, payload, QoS) o topic’in retained mesajı olarak saklar ve varsa öncekinin yerine koyar. Her topic için en fazla bir retained mesaj bulunur.
  3. Daha sonra bir client bu topic’le eşleşen bir filtreyle abone olduğunda broker, retained mesajı SUBACK’in hemen ardından gönderir; client’ın bunun saklanmış bir değer olduğunu anlaması için retain bayrağı set edilmiş olur.
Retained mesaj zaman çizelgesi
10:00  device   PUBLISH  acme/th-01/setpoint  "21.0"  retain=1   -> broker stores it
10:05  device   PUBLISH  acme/th-01/setpoint  "22.5"  retain=1   -> replaces "21.0"
10:30  app      SUBSCRIBE acme/+/setpoint
10:30  broker   PUBLISH  acme/th-01/setpoint  "22.5"  retain=1   -> delivered instantly

Wildcard abonelikleri, eşleşen her topic’in retained mesajlarını alır; acme/+/status filtresine abone olan bir pano, açılışta tüm cihazların durumunu bu sayede gösterebilir.

Teslimatta retain bayrağı

MQTT 3.1.1’de mevcut bir subscriber’a iletilen mesajın retain bayrağı her zaman temizlenir; bayrak yalnızca mesaj yeni bir abonelik nedeniyle gönderildiğinde set edilir. MQTT 5 bu varsayılanı korur ancak orijinal bayrağı koruyan Retain As Published abonelik seçeneğini ekler — köprüler (bridge) için kullanışlıdır.

Retained mesajlar olmasaydı yeni açılan bir pano, her cihaz tesadüfen tekrar publish edene kadar boş kutucuklar gösterirdi — bu da bir kapı sensörü veya bir yapılandırma değeri için saatler sürebilir. Retained mesajlarla ilk ekran zaten doğrudur.

Retained mesajlar ne zaman kullanılır?

  • Cihaz durumu — online/offline, açık/kapalı, mevcut mod.
  • Yapılandırma ve setpoint’ler — yeniden başlayan bir cihaz abone olur ve yapılandırmasını hemen alır.
  • Yavaş değişen değerler — firmware sürümü, konum, bilinen son ölçüm.
  • Çevrimiçi durumu (presence) — retained bir Last Will mesajıyla birlikte, böylece çevrimdışı durumu kalıcı olur.

Şunları retained olarak göndermekten kaçının:

  • Olaylar ve komutlar — retained bir unlock-door komutu her yeni subscriber’a, belki günler sonra, yeniden oynatılır.
  • Yüksek frekanslı akışlar — bir sonraki değer bir saniye içinde geliyorsa retain zararsızdır ama anlamsızdır.
  • Mesaj başına topic’ler — ID veya zaman damgası içeren topic’ler arkalarında binlerce eskimiş retained mesaj bırakır.

Retained mesaj nasıl silinir?

Retained bir mesajı silmek için aynı topic’e retain bayrağı set edilmiş ve sıfır uzunlukta bir payload’la publish edin. Broker saklanan mesajı kaldırır ve boş mesajı saklamaz. Mevcut subscriber’lar boş mesajı alır; bu yüzden kodunuzun boş payload’ları yok saymasını sağlayın.

mosquitto_pub ile retained mesajı silmek
# -r = retain, -n = send a null (zero-length) payload
mosquitto_pub -h broker.hivemq.com -t 'testmqtt/demo/status' -r -n
MQTT.js ile retained mesajı silmek
client.publish('testmqtt/demo/status', '', { retain: true, qos: 1 });

Birçok topic’i aynı anda temizlemek için bir wildcard ile abone olun, retain bayrağıyla mesaj teslim eden her topic’i toplayın ve her birine boş bir retained payload publish edin. Standart bir “tüm retained mesajları sil” komutu yoktur — bazı broker’lar yönetim araçları sunar, ancak bunlar broker’a özgüdür.

Retained mesajlar ve kalıcı oturumlar

Retained mesajlar sıklıkla kalıcı oturumlarla (persistent session) karıştırılır, ancak farklı sorulara yanıt verirler:

Retained mesajKalıcı oturum
KapsamTopic başına, tüm subscriber’larca paylaşılırClient ID başına
Ne saklanırYalnızca en son mesajAbonelikler ve kaçırılan her QoS 1/2 mesajı
Kim alırSonradan abone olan herhangi bir clientYalnızca o client, yeniden bağlandığında
Tipik kullanımGüncel durumOlayları kaçırmamak

Hem güncel yapılandırmasına hem de çevrimdışıyken gönderilen her komuta ihtiyaç duyan bir cihaz ikisini birden kullanır: retained bir yapılandırma topic’i ve komut topic’i için kalıcı bir oturum. Oturumların ve QoS’un nasıl etkileştiğini QoS rehberi açıklıyor.

Retained mesajlar QoS’larını da korur. Broker saklanan bir mesajı yeni bir subscriber’a teslim ederken olağan düşürme kuralı geçerlidir: subscriber mesajı, orijinal QoS ile abonelik QoS’undan düşük olanıyla alır.

MQTT 5’te retained mesajlar

MQTT 5, retained mesajlar üzerinde daha ince bir kontrol sağlar:

ÖzellikNe yapar
Retain Handling (abonelik seçeneği)0 = abone olunca retained mesajları gönder (varsayılan), 1 = yalnızca abonelik yeniyse, 2 = hiçbir zaman gönderme
Retain As Published (abonelik seçeneği)İletilen mesajlarda orijinal retain bayrağını korur
Message Expiry Interval (publish özelliği)Broker, retained mesajı belirtilen saniye sonunda siler
Retain Available (CONNACK özelliği)Client’a broker’ın retained mesajları destekleyip desteklemediğini bildirir

Message expiry özellikle kullanışlıdır: bir saat sonra süresi dolan retained bir sensör ölçümü asla yeni bir ölçümle karıştırılamaz. Değişikliklerin tam listesi için MQTT 5 ve 3.1.1 yazısına bakın.

Retained mesajları test edin

  1. Retain işaretliyken testmqtt/your-id/status topic’ine online publish edin.
  2. Bağlantıyı kesin, yeniden bağlanın ve testmqtt/your-id/# filtresine abone olun. Mesaj, retained olarak işaretlenmiş şekilde anında gelir.
  3. Retain işaretliyken boş bir payload publish edin, yeniden abone olun — hiçbir şey gelmez. Retained mesaj silinmiştir.

Online MQTT istemcisinde deneyin

Online MQTT client, saklanan mesajlarda bir retained etiketi gösterir; bu da eskimiş durumu fark etmeyi kolaylaştırır. Daha kapsamlı bir kontrol listesi için MQTT broker nasıl test edilir yazısına bakın.

Sıkça sorulan sorular

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

Aynı topic’e retain bayrağı set edilmiş ve sıfır uzunlukta (boş) payload içeren bir mesaj publish edin. Broker saklanan retained mesajı kaldırır ve boş mesajı saklamaz. mosquitto_pub ile -r -n kullanın.

Bir topic’in kaç retained mesajı olabilir?

Bir tane. Broker her topic için yalnızca en son retained mesajı saklar; her yeni retained publish bir öncekinin yerini alır.

Retained mesaj, kalıcı oturumla aynı şey mi?

Hayır. Retained mesaj bir topic’in son değeridir ve her yeni subscriber’a teslim edilir. Kalıcı oturum ise belirli bir client çevrimdışıyken onun için mesajları kuyruğa alır. Farklı sorunları çözerler ve sıklıkla birlikte kullanılırlar.