MQTT mesaj sona erme süresi (message expiry interval), broker'a bir mesajın kaç saniye geçerli kalacağını söyleyen bir MQTT 5 property'sidir. Bu süre geçtiğinde broker, mesajı geç yeniden bağlanan bir istemciye iletmek yerine atar. Bu makalede süre dolumunun tam olarak nasıl çalıştığını öğrenecek, canlı bir testte eskimiş bir komutu düşürdüğünü görecek ve kendi sisteminizde sona erme değerlerini seçmek için bir kontrol listesi edineceksiniz.
Sorun: Çok Geç Gelen Komutlar
QoS 1 ve kalıcı bir oturumla subscribe olmuş bir cihaz düşünün. Cihaz çevrimdışıyken bir operatör "kapıyı aç" komutu gönderir. Oturum hâlâ canlı olduğu için broker komutu kuyruğa alır. İki saat sonra cihaz kararsız bir hücresel bağlantı üzerinden yeniden bağlanır ve broker görev bilinciyle "kapıyı aç" komutunu iletir. Artık kapıda bekleyen kimse yoktur.
MQTT 5'ten önce bunu durdurmanın protokol düzeyinde bir yolu yoktu. Geliştiriciler payload'lara zaman damgası ekler ve her cihazın bunları kontrol ettiğini umardı. MQTT 5, çözümü PUBLISH paketindeki bir property olan message expiry interval ile protokolün içine taşıdı. Fiziksel ekipmanı kontrol eden herkes için en pratik MQTT 5 özelliklerinden biridir.
MQTT Mesaj Sona Erme Süresi Nasıl Çalışır?
Publisher property'yi saniye cinsinden, dört baytlık bir tam sayı olarak ayarlar. Broker ardından şu kuralları uygular:
- Mesaj geldiğinde broker zamanı kaydeder.
- Mesaj, kalıcı oturuma sahip çevrimdışı bir subscriber için kuyruğa alınmışsa ve teslimattan önce süre dolarsa broker mesajı atar.
- Broker mesajı teslim ettiğinde property'yi kalan süreyle yeniden yazar. 60 saniyeyle publish edilip 45 saniye sonra teslim edilen bir mesaj 15 değeriyle ulaşır.
- Mesaj retained ise retained kopyanın da süresi dolar. Süre geçtikten sonra yeni subscriber'lar onu artık almaz.
- Property yoksa mesajın süresi hiçbir zaman dolmaz; bu MQTT 3.1.1 davranışıdır.
Dördüncü kural, süre dolumunu komutların ötesinde de yararlı kılar. Retained bir "bakım modu aktif" banner'ı kendiliğinden sona erecek şekilde ayarlanabilir; böylece unutulan bir bayrak haftalarca ortalıkta kalmaz.
| Mesaj tipi | Önerilen süre | Gerekçe |
|---|---|---|
| Aktüatör komutu (aç, başlat, durdur) | 5 ila 60 sn | Yalnızca bir operatör izlerken geçerlidir |
| Yapılandırma gönderimi | Saatler ila günler | Cihaz daha sonra yeniden bağlandığında hâlâ işe yarar |
| Kalıcı bir tüketiciye giden telemetri | Dakikalar | Eski ölçümler değer kaybeder ama boşlukları doldurabilir |
| Retained geçici durum | Durumun süresi kadar | Kendiliğinden temizlenir |
| Alarm bildirimi | Artık eyleme dönüştürülemez hale gelene kadar | Eskimiş alarm selinden kaçının |
Süre Dolumunun Önem Kazanması İçin Neden Kalıcı Oturumlar Gerekir?
Süre dolumu yalnızca bir yerde bekleyen mesajları etkiler. Saklanan durumu olmayan clean bir oturumda bağlantısı kopan subscriber mesajları kaçırır; dolayısıyla süresi dolacak bir şey yoktur. Süre dolumu iki yerde önemlidir:
- Oturum kuyrukları. Clean start false olarak ve sıfırdan büyük bir session expiry interval ile bağlanan bir istemcinin QoS 1 ve QoS 2 mesajları çevrimdışıyken kuyruğa alınır. Bu kuyruğun nasıl oluşturulduğunu açıklayan MQTT session expiry interval yazısına bakın.
- Retained depolama. Süre dolumu ayarlanmış retained bir mesaj, süre geçtikten sonra kaldırılır.
İki süre ayarı arasındaki farka dikkat edin: Session expiry, broker'ın bir istemciyi ne kadar süre hatırlayacağını kontrol eder; message expiry ise tek bir mesajın ne kadar süre teslim edilmeye değer olduğunu kontrol eder. Genellikle ikisini birden istersiniz.
Canlı Bir Broker'da Mesaj Süre Dolumunu Test Etmek
MQTT 5'i ve 30 dakikaya kadar oturumları destekleyen broker.connectmq.com adresindeki herkese açık MQTT test broker'ını kullanacağız. Kendi topic önekinizi kullanın.
Adım 1: Kalıcı bir oturum oluşturun. Clean start devre dışı (-c), 600 saniyelik session expiry (-x 600) ve QoS 1 ile bir kez bağlanın, ardından Ctrl+C ile durdurun:
mosquitto_sub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-dev-m4t9 \
-c -x 600 -q 1 -t connectmq/demo/m4t9/gate/cmd -v
Adım 2: Subscriber çevrimdışıyken, süresi 10 saniyede dolan bir komut ve 5 dakika geçerli olan bir komut publish edin:
mosquitto_pub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-op-m4t9 -q 1 \
-t connectmq/demo/m4t9/gate/cmd -m 'open (10s)' \
-D publish message-expiry-interval 10
mosquitto_pub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-op-m4t9 -q 1 \
-t connectmq/demo/m4t9/gate/cmd -m 'report-status (300s)' \
-D publish message-expiry-interval 300
Adım 3: En az 20 saniye bekleyin, ardından 1. adımdaki komutun aynısıyla yeniden bağlanın. Yalnızca report-status (300s) gelir. Open komutunun süresi kuyrukta dolmuştur ve hiç teslim edilmemiştir. 2. ve 3. adımları hızla, 10 saniye içinde tekrar çalıştırın; bu kez her iki mesaj da gelir.
Python ve Node.js'te Süre Dolumunu Ayarlamak
paho-mqtt 2.x'te publish işlemine bir Properties nesnesi eklersiniz. İstemcinin MQTT 5 kullanması gerekir:
import json
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id=f"op-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5,
)
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
props = Properties(PacketTypes.PUBLISH)
props.MessageExpiryInterval = 30 # saniye
cmd = {"action": "open", "issuedBy": "operator-3"}
info = client.publish("connectmq/demo/m4t9/gate/cmd", json.dumps(cmd), qos=1, properties=props)
info.wait_for_publish()
client.loop_stop()
client.disconnect()
Alıcı tarafta msg.properties, kalan saniyeleri içeren MessageExpiryInterval değerini barındırır; bir cihaz bunu loglayabilir ya da süresi neredeyse dolmuş komutları reddetmek için kullanabilir.
MQTT.js v5'te property, publish seçeneklerinde yer alır:
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId: "op-" + Math.random().toString(16).slice(2, 10),
protocolVersion: 5,
});
client.on("connect", () => {
client.publish(
"connectmq/demo/m4t9/gate/cmd",
JSON.stringify({ action: "close" }),
{ qos: 1, properties: { messageExpiryInterval: 30 } },
(err) => {
if (err) console.error(err);
client.end();
}
);
});
Tuzaklar ve Sorun Giderme
Süre dolumu tamamen yok sayılıyor. Hem publisher'ın hem de broker bağlantısının MQTT 5 kullandığını kontrol edin. Bir 3.1.1 istemcisi property'yi gönderemez ve bir 3.1.1 subscriber'ı mesajı property olmadan alır.
Mesaj yine de geç ulaşıyor. Süre dolumu, broker kuyruğundan teslimatı durdurur. Mesaj zaten cihazın kendi tamponunda veya aradaki bir gateway'de bekliyorsa işe yaramaz. Komut çalıştıran cihazlar, güvenliğin önemli olduğu durumlarda payload'daki bir zaman damgasını kendi saatleriyle yine de karşılaştırmalıdır.
Komutların süresi çok çabuk doluyor. Ağ ve broker kuyruğu gecikmesini unutmayın. 1 veya 2 saniyelik bir süre, yavaş bağlantılarda meşru komutları atabilir.
Retained mesaj kayboldu. Biri retained değeri bir süre dolumuyla publish ettiyse, süre geçtiğinde değer kaybolur. Bu çoğu zaman bilinçlidir; veri kaybı olduğunu varsaymadan önce publisher'ı kontrol edin. Retained temelleri için MQTT retained mesajlar yazısına bakın.
Süre dolumu ve QoS. QoS bir mesajın teslim edilip edilmeyeceğini, süre dolumu ise hâlâ teslim edilmeye değer olup olmadığını kontrol eder. Süre dolumu ayarlanmış bir QoS 1 mesajının hiç ulaşmaması tamamen meşrudur.
Süre Dolumunu Diğer Güvenlik Önlemleriyle Birleştirmek
Mesaj süre dolumu bir savunma katmanıdır, tasarımın tamamı değil. Fiziksel ekipmanı hareket ettiren komutlar için sağlam bir kurulum genellikle birkaç mekanizmayı birleştirir:
- Broker'ın eskimiş komutları kuyruklardan atması için her komutta süre dolumu.
- Bir gateway onu tamponlamış olsa bile cihazın kendi eşiğinden eski her şeyi reddedebilmesi için payload'da bir komut ID'si ve gönderim zaman damgası.
- Bir yeniden başlatmanın eski bir talimatı asla tekrar oynatmaması için komutlarda retain bayrağı olmaması.
- Cihazın komutu çalıştırdığını veya reddettiğini bildirdiği, ideal olarak MQTT istek-yanıt deseni kullanan bir onay topic'i.
- Güvenlikle ilgili her şey için cihaz üzerinde kilitlemeler (interlock). Güvenli olmayan bir eylemi engelleyen tek şey asla ağ olmamalıdır.
Süre dolumunu kuyrukları temiz tutan ve geç teslimatı nadir hale getiren araç olarak düşünün; cihaz tarafındaki kontroller ise geç çalıştırmayı imkânsız kılar.
ConnectMQ'da Mesaj Süre Dolumu
ConnectMQ, MQTT 5.0 bağlantılarında message expiry, session expiry, response topic ve diğer MQTT 5 property'leriyle MQTT 5.0'ı destekler. Production için operatör araçlarınızı ve cihazlarınızı portaldan alınan kimlik bilgileriyle 8883 portu üzerinden TLS ile bağlayın ve her komut topic'inde süre dolumunu bir politika olarak ayarlayın. Yönetilen bir MQTT broker, oturum deposunu ve kuyrukları çalıştırma işini üstlenir; böylece ekibinizin yalnızca makul süre değerleri seçmesi gerekir. MQTT eğitimi kalan temel konuları ele alıyor.
ConnectMQ ile Başlayın
app.connectmq.com adresinde kredi kartı gerekmeden Serverless planda ücretsiz bir broker oluşturun. MQTT 5 ile bağlanın, ilk komutunuza bir süre dolumu ekleyin ve onu geç yeniden bağlanan bir cihaza karşı test edin. Bunu bir bulut MQTT broker üzerinde çalıştırmak, deneme yaparken bakımını yapacağınız sunucu olmaması demektir.
Sık Sorulan Sorular
Mesaj sona erme süresi hangi birimi kullanır?
Dört baytlık işaretsiz bir tam sayı olarak saklanan saniyeleri. Property ayarlanmamışsa mesajın süresi dolmaz.
Subscriber orijinal süre değerini görür mü?
Hayır. Broker kalan süreyi gönderir; böylece subscriber mesaj ulaştığında ne kadar geçerlilik kaldığını anlayabilir.
Mesaj süre dolumu MQTT 3.1.1 ile çalışır mı?
Hayır. Bu bir MQTT 5 property'sidir. MQTT 3.1.1'de alıcının kendisinin kontrol ettiği, payload içinde bir zaman damgasına ihtiyacınız vardır.
Retained mesajların süresi dolabilir mi?
Evet. Bir sona erme süresiyle publish edilen retained bir mesaj, süre geçtikten sonra retained depolamadan kaldırılır.



