MQTT Temelleri

LWT ve Retained Mesajlarla MQTT Cihaz Çevrimiçi/Çevrimdışı Durumu

MQTT filoları için adım adım bir varlık (presence) deseni: retained birth mesajları, retained bir Last Will, düzgün kapanış mesajları ve her cihazın durumunu gerçek zamanlı izleyen bir monitör.

Her cihaz için MQTT cihaz çevrimiçi durumunu yeşil ve gri göstergelerle gösteren filo dashboard'u
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

Şu anda hangi cihazların bağlı olduğunu bilmek her operatörün ilk istediği şeydir ve MQTT cihaz çevrimiçi durumunu yanlış kurmak şaşırtıcı derecede kolaydır. Güvenilir desen üç yapı taşını birleştirir: retained bir birth mesajı, retained bir Last Will ve kapanışta açıkça gönderilen bir offline mesajı. Bu rehberde bu deseni adım adım kuracak, Python ile bir filo monitörü ekleyecek ve dashboard'ların yanlış bilgi göstermesine neden olan uç durumlardan nasıl kaçınacağınızı öğreneceksiniz.

Yapı Taşları

Her parça sorunun bir bölümünü çözer:

Yapı taşı Kim publish eder Ne zaman Neyi kapsar
Birth mesajı (online, retained) Cihaz Her başarılı bağlantıdan hemen sonra Cihaz açık; yeniden bağlantılar dahil
Last Will (offline, retained) Cihaz adına broker Bağlantı DISCONNECT olmadan koptuğunda Çökmeler, güç kaybı, ağ arızası
Kapanış mesajı (offline, retained) Cihaz Temiz bir bağlantı kesmeden önce Planlı yeniden başlatmalar ve kapanışlar
Üçünde de retain bayrağı Hepsi Her zaman Sonradan açılan dashboard'lar da güncel durumu görür

Herhangi birini atlarsanız kör bir nokta oluşur. Birth mesajı olmadan toparlanan bir cihaz "offline" kalır. Will olmadan çökmeler fark edilmez. Kapanış mesajı olmadan planlı bir kapanış cihazı sonsuza kadar "online" bırakır, çünkü temiz bir DISCONNECT broker'a will'i atmasını söyler. Will mekanizması sizin için yeniyse önce MQTT Last Will and Testament yazısını okuyun.

Durum Topic'ini Tasarlamak

Her cihaza öngörülebilir bir yerde tam olarak bir durum topic'i verin:

connectmq/demo/<prefix>/<site>/<device-id>/status

Böylece connectmq/demo/<prefix>/+/+/status gibi bir wildcard, tek bir subscription ile tüm filonun durumunu döndürür. Tüm durum mesajları retained olduğundan, başlatılan bir monitör her cihazın bilinen son durumunu anında alır. Saklamanın nasıl çalıştığı MQTT retained mesajlar yazısında anlatılıyor.

Payload için birçok araçta düz bir online veya offline string'i yeterlidir. JSON ise operasyonlara yardımcı olan bağlam ekler:

{"state":"online","ts":1760600000,"fw":"2.4.1","ip":"10.0.4.17","reason":"boot"}

Will için cihaz gelecekteki bir arızanın zaman damgasını bilemez; bu yüzden basit tutun: {"state":"offline","reason":"lwt"}. Monitör, mesajı ne zaman aldığını kaydeder.

Adım 1: Cihaz

Bu paho-mqtt 2.x betiği iyi tasarlanmış bir cihaz gibi davranır. Bağlanmadan önce retained bir will ayarlar, her yeniden bağlantıdan sonra tekrarlanması için on_connect içinde retained bir birth mesajı publish eder ve düzgün kapanışta retained bir offline mesajı publish eder. broker.connectmq.com adresindeki herkese açık MQTT test broker'ına bağlanır:

import json
import signal
import sys
import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
DEVICE_ID = sys.argv[1] if len(sys.argv) > 1 else "pump-07"
STATUS = f"connectmq/demo/z8b2/plant1/{DEVICE_ID}/status"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"z8b2-{DEVICE_ID}")
client.will_set(STATUS, json.dumps({"state": "offline", "reason": "lwt"}),
                qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=30)

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("connect failed:", reason_code)
        return
    birth = {"state": "online", "ts": int(time.time()), "reason": "connect"}
    client.publish(STATUS, json.dumps(birth), qos=1, retain=True)
    print("online")

def shutdown(signum, frame):
    bye = {"state": "offline", "ts": int(time.time()), "reason": "shutdown"}
    client.publish(STATUS, json.dumps(bye), qos=1, retain=True).wait_for_publish(timeout=5)
    client.disconnect()
    client.loop_stop()
    sys.exit(0)

client.on_connect = on_connect
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)

client.connect(BROKER, 1883, keepalive=20)
client.loop_start()
while True:
    time.sleep(1)  # gerçek telemetri burada publish edilir

Bunu python device.py pump-07 olarak, başka bir terminalde de python device.py fan-02 olarak çalıştırın.

Adım 2: Filo Monitörü

Monitör tüm durum topic'lerine subscribe olur ve cihazların bir tablosunu tutar. Durumlar retained olduğundan, başladıktan birkaç saniye sonra tüm filonun durumunu bilir:

import json
import time
import uuid
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
FILTER = "connectmq/demo/z8b2/+/+/status"
fleet = {}

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

def on_message(client, userdata, msg):
    device = msg.topic.split("/")[-2]
    if not msg.payload:  # boş retained payload = cihaz kaldırıldı
        fleet.pop(device, None)
        return
    try:
        state = json.loads(msg.payload).get("state", "unknown")
    except ValueError:
        state = msg.payload.decode(errors="replace")
    previous = fleet.get(device, {}).get("state")
    fleet[device] = {"state": state, "since": time.strftime("%H:%M:%S")}
    tag = "retained" if msg.retain else "live"
    if previous != state:
        print(f"[{tag}] {device}: {previous} -> {state}")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"monitor-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=30)
client.loop_forever()

Adım 3: Her Arıza Senaryosunu Test Edin

Monitörü ve iki cihazı çalıştırın, ardından bu kontrol listesini sırayla uygulayın ve monitörün her seferinde doğru tepki verdiğini doğrulayın:

  1. Monitörü yeniden başlatma. Monitörü durdurup başlatın. Her iki cihaz da retained etiketiyle anında online olarak görünür.
  2. Düzgün kapanış. fan-02 üzerinde Ctrl+C'ye basın. Monitör hemen shutdown nedeniyle offline gösterir.
  3. Çökme. pump-07'yi kill -9 ile sonlandırın. İşletim sistemi soketi kapatır, broker will'i publish eder ve monitör offline gösterir.
  4. Sessiz ağ kaybı. Süreci sonlandırmadan cihazın ağ bağlantısını kesin. 20 saniyelik keepalive'ın yaklaşık 1,5 katı süre sonra will tetiklenir.
  5. Toparlanma. Ağı geri getirin. paho yeniden bağlanır, on_connect çalışır ve birth mesajı cihazı yeniden online yapar.
  6. Hizmetten çıkarma. Durum topic'ine boş bir retained mesaj publish edin. Monitör cihazı kaldırır.

Aynı topic'leri tarayıcıda da canlı izleyebilirsiniz; cihazları kendi broker'ınıza yönlendirdiğinizde ConnectMQ portalındaki tarayıcı içi istemci ve topic gezgini durum değişikliklerini anında gösterir.

Dashboard'ları Yanıltan Uç Durumlar

Yinelenen client ID'ler. Aynı ID'ye sahip iki cihaz birbirini düşürür. Her devralma bir will ve bir birth tetikleyebilir; bu yüzden durum sürekli gidip gelir. Benzersiz ID'ler pazarlık konusu değildir; bkz. MQTT client ID rehberi.

Birth yalnızca açılışta bir kez publish ediliyor. online mesajını bağlantı callback'inin dışında publish ederseniz, bir ağ aksaklığından sonra yeniden bağlanan cihaz sonsuza kadar offline kalır. Bunu her zaman her bağlantıda publish edin.

Will retained değil. Arızadan sonra açılan bir dashboard bundan asla haberdar olmaz.

Hızlı yeniden bağlantıların yol açtığı titreşim. Saniyeler içinde yeniden bağlanan bir cihaz yine de bir offline/online çifti üretir. MQTT 5'te bir will delay interval, oturum zamanında devam ederse will'i bastırır.

Uzun keepalive. 300 saniyelik keepalive ile ölü bir cihaz yedi dakikadan uzun süre çevrimiçi görünür. Ne kadar hızlı haberdar olmanız gerektiğine uygun bir keepalive seçin.

"Bağlı" demek "sağlıklı" demek değildir. Bir cihaz, sensörü arızalanmışken MQTT bağlantısını sürdürebilir. Uygulama düzeyinde canlılık gerekiyorsa ayrı bir sağlık veya heartbeat alanı publish edin.

Presence ve Heartbeat: Hangisine İhtiyacınız Var?

Bağlantıya dayalı presence ve uygulama heartbeat'leri farklı soruları yanıtlar ve birçok filonun ikisine de ihtiyacı vardır.

Sinyal Yanıtladığı soru Tespit süresi Maliyet
Durum topic'inde Birth + LWT Cihaz broker'a bağlı mı? Anında ile 1,5 x keepalive arası Neredeyse hiç; yalnızca keepalive ping'leri
Periyodik heartbeat mesajı Uygulama döngüsü hâlâ çalışıyor mu? Bir veya iki heartbeat aralığı Aralık başına küçük bir publish
Telemetri tazelik kontrolü Sensör hâlâ veri üretiyor mu? Beklenen publish hızına bağlı Cihazda yok; mantık tüketicide

MQTT client kendi thread'inde çalışıyorsa, ana döngüsü takılmış bir cihaz keepalive ping'lerine yanıt vermeye devam edebilir ve bağlantı durumu online kalır. Ana döngüden publish edilen bir heartbeat veya telemetrisi eskimiş cihazları işaretleyen bir tüketici bu durumu yakalar. Heartbeat'leri retained yapmayın ve sıklıklarını makul tutun; çoğu izleme için dakikada bir fazlasıyla yeterlidir.

Durum Topic'lerini Diğer Araçlarda Kullanmak

Desen yalnızca retained MQTT mesajlarından oluştuğu için MQTT destekli her araç bunu özel bir entegrasyon olmadan tüketebilir. Node-RED'de durum wildcard'ına subscribe olan bir mqtt in node'u bir dashboard'u veya bildirim akışını besler. Home Assistant'ın MQTT entegrasyonu bir durum topic'ini online ve offline payload'larıyla bir availability ayarına eşleyebilir. Telegraf'ın MQTT consumer girişi, çalışma süresi raporlaması için durum değişikliklerini bir zaman serisi veritabanına yazabilir. Bunların her biri broker'a sıradan bir MQTT client'ı olarak bağlanır; tek gereklilik topic adları ve payload değerleri üzerinde anlaşmaktır. Hazır araçlar kullanmayı planlıyorsanız düz online ve offline string'leri en taşınabilir seçimdir; JSON ise kendi kodunuz için daha zengin bağlam sunar.

ConnectMQ'da Broker Tarafı Durum

Yukarıdaki desen her broker'a taşınabilir. Buna ek olarak ConnectMQ, bağlantı durumunu $SYS/broker/connection/{clientId}/state üzerinde publish eder; bir monitör buna, cihaz firmware'inin will'ini doğru yapılandırmasına bağlı olmayan bağımsız bir kaynak olarak subscribe olabilir. Portalın cihazlar görünümü cihazlarınızı ISA-95 seviyelerine göre düzenler ve eşik alarm kuralları sınırları aşan değerler hakkında sizi bilgilendirebilir. Üretim için portaldaki YOUR_USERNAME, YOUR_PASSWORD ve YOUR_CLIENT_ID bilgileriyle 8883 portunda TLS kullanın. Yönetilen bir MQTT broker, presence altyapısını sizin yerinize çalışır halde tutar; arkasındaki temeller için MQTT eğitimine bakın.

ConnectMQ ile Başlayın

app.connectmq.com adresinde, kredi kartı gerekmeden Serverless planında ücretsiz bir broker oluşturun. Cihaz ve monitör betiklerini kimlik bilgilerinizle dağıtın; dakikalar içinde bir bulut MQTT broker'ında güvenilir filo presence'ına sahip olursunuz.

Sık Sorulan Sorular

Cihazım kapatıldıktan sonra neden çevrimiçi görünüyor?

Temiz bir DISCONNECT, Last Will'i atar. Bağlantıyı kesmeden önce retained bir offline mesajını kendiniz publish edin.

Cihazım yeniden bağlandıktan sonra neden çevrimdışı kalıyor?

Birth mesajı muhtemelen yalnızca açılışta bir kez publish ediliyor. Her yeniden bağlantının durumu güncellemesi için onu on-connect callback'inde publish edin.

Çevrimdışı bir cihaz ne kadar hızlı tespit edilir?

TCP bağlantısı kapanırsa anında. Cihaz sessizce kaybolursa keepalive aralığının yaklaşık 1,5 katı sürede.

Durum mesajları retained olmalı mı?

Evet. Birth, will ve kapanış mesajlarını retained yapmak, sonradan subscribe olan her client'ın güncel durumu hemen almasını sağlar.

İ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.