Protokol IoT

Panduan Lengkap MQTT: Protokol Ringan untuk IoT

πŸ”‘ Token

Tutorial komprehensif MQTT dari konsep publish-subscribe, instalasi broker Mosquitto, penggunaan client Python hingga ESP32 β€” dilengkapi QoS, keamanan TLS/SSL, dan perbandingan dengan protokol lain

1. Apa itu MQTT?

MQTT (Message Queuing Telemetry Transport) adalah protokol komunikasi jaringan ringan yang dirancang khusus untuk pertukaran pesan antar perangkat di jaringan dengan bandwidth rendah, latensi tinggi, atau koneksi yang tidak stabil. MQTT menjadi standar de facto komunikasi di dunia Internet of Things (IoT).

MQTT pertama kali dikembangkan oleh Andy Stanford-Clark (IBM) dan Arlen Nipper pada tahun 1999 untuk memantau pipa gas minyak di gurun Sahara melalui satelit. Keterbatasan bandwidth satelit saat itu membutuhkan protokol yang sangat efisien dalam penggunaan paket data.

Diagram: Alur Komunikasi Publish-Subscribe MQTT
πŸ“‘
Publisher
ESP32 / Sensor
Topik: "rumah/suhu"
β†’ Publish
πŸ–₯️
MQTT Broker
Server Pusat
Meneruskan pesan ke subscriber
← Deliver
πŸ“Š
Subscriber
Dashboard / Mobile App
Menerima dari topik
Topic: Label/jalur pesan, contoh: "rumah/suhu" Payload: Isi pesan, contoh: {"suhu": 28.5}

Fitur Utama MQTT

πŸ’‘ Kenapa MQTT Populer untuk IoT?

Menggunakan HTTP untuk komunikasi IoT seperti mengirim truk untuk mengantar satu amplop. MQTT lebih seperti sistem radio β€” ringan, cepat, dan efisien. Dengan header hanya 2 byte dibanding HTTP yang rata-rata 800 byte per request, MQTT jauh lebih hemat bandwidth dan daya baterai.

2. Arsitektur MQTT

MQTT berdiri di atas empat komponen inti: Broker, Client (Publisher & Subscriber), Topic, dan Quality of Service (QoS). Memahami komponen-komponen ini adalah kunci untuk membangun sistem IoT yang stabil dan efisien.

2.1 MQTT Broker

Broker adalah server pusat yang menjadi pengelola semua komunikasi MQTT. Broker bertanggung jawab menerima pesan dari publisher, meneruskannya ke subscriber yang sesuai, mengelola sesi koneksi client, serta menyimpan pesan retained dan session data.

Broker MQTT yang paling banyak digunakan antara lain:

2.2 MQTT Client

Client adalah perangkat atau aplikasi yang terhubung ke broker. Client bisa berperan sebagai publisher, subscriber, atau keduanya sekaligus. Contoh client:

2.3 Topic (Topik)

Topic adalah label atau jalur pesan yang digunakan untuk mengatur ke mana pesan dikirim. Topik menggunakan struktur hierarki dipisah oleh garis miring (/). Broker memutuskan ke subscriber mana pesan akan dikirim berdasarkan kecocokan topik.

Contoh Struktur Topik MQTT
# === Struktur Topik Hierarki ===

# Data sensor per ruangan
rumah/lantai1/ruang_tamu/suhu
rumah/lantai1/kamar_tidur/kelembaban
rumah/lantai1/dapur/pintu

# Data kendaraan fleet
fleet/mobil-001/posisi/lat
fleet/mobil-001/posisi/lng
fleet/mobil-001/bbm/persen

# Topik dengan wildcard
rumah/+/suhu           ← Wildcard single level (+)
rumah/#                ← Wildcard multi level (#)
rumah/lantai1/#/suhu   ← Kombinasi wildcard

# Topik dengan placeholder (MQTT v5)
devices/{device_id}/telemetry
Wildcard Fungsi Contoh
+Menggantikan satu level topikrumah/+/suhu mencocokkan rumah/lantai1/suhu
#Menggantikan satu atau lebih levelrumah/# mencocokkan rumah/lantai1/ruang_tamu/suhu
⚠️ Aturan Penamaan Topik

Topik MQTT bersifat case-sensitive. Pastikan publisher dan subscriber menggunakan topik yang persis sama. Topik tidak boleh dimulai atau diakhiri dengan karakter /. Topik kosong ("") digunakan sebagai topik root. Panjang maksimal topik adalah 65535 byte.

2.4 Quality of Service (QoS)

MQTT mendukung tiga level QoS yang menentukan tingkat keandalan pengiriman pesan:

⚑
QoS 0 β€” At Most Once
  • βœ… Paling cepat & ringan
  • βœ… Tanpa konfirmasi
  • ❌ Pesan mungkin hilang
  • ❌ Tidak ada jaminan
πŸ”„
QoS 1 β€” At Least Once
  • βœ… Jaminan pesan sampai
  • βœ… Konfirmasi PUBACK
  • ❌ Pesan mungkin duplikat
  • ❌ 2 pesan jaringan
πŸ”’
QoS 2 β€” Exactly Once
  • βœ… Tepat sekali, tidak duplikat
  • βœ… 4-way handshake
  • ❌ Paling lambat
  • ❌ Overhead paling besar

3. Instalasi Mosquitto Broker

Mosquitto adalah broker MQTT open-source yang dikembangkan oleh Eclipse Foundation. Mosquitto ringan, mudah dikonfigurasi, dan mendukung MQTT 3.1.1 serta MQTT 5.0. Berikut panduan instalasi di Ubuntu dan Windows.

3.1 Instalasi di Ubuntu / Debian

Terminal β€” Instalasi Mosquitto di Ubuntu
# === Update repository dan instal Mosquitto ===
sudo apt update
sudo apt install -y mosquitto mosquitto-clients

# === Aktifkan dan jalankan layanan Mosquitto ===
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

# === Cek status layanan ===
sudo systemctl status mosquitto

# === Verifikasi versi ===
mosquitto -v

# === Test publish dari terminal ===
# Buka terminal 1 β€” Subscriber
mosquitto_sub -h localhost -t "test/hello" -v

# Buka terminal 2 β€” Publisher
mosquitto_pub -h localhost -t "test/hello" -m "Halo dari Mosquitto!"
Output terminal subscriber: test/hello Halo dari Mosquitto! test/hello IoT berjalan dengan lancar!

3.2 Konfigurasi Mosquitto

File konfigurasi Mosquitto terletak di /etc/mosquitto/mosquitto.conf. Berikut konfigurasi dasar untuk penggunaan lokal:

mosquitto.conf β€” Konfigurasi Dasar
# === Konfigurasi Mosquitto Broker ===
# File: /etc/mosquitto/mosquitto.conf

# Port listener
listener 1883

# Log
log_dest syslog
log_dest stdout
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true

# Persistence (simpan data subscriber ke disk)
persistence true
persistence_location /var/lib/mosquitto/

# Anonymous access (untuk testing saja)
allow_anonymous true

# Max connections (0 = unlimited)
max_connections -1
⚠️ Keamanan Default

Mulai dari versi Mosquitto 2.0, anonymous access dinonaktifkan secara default untuk alasan keamanan. Jika Anda mendapat error Client disconnected due to protocol error, tambahkan allow_anonymous true di konfigurasi atau buat file /etc/mosquitto/passwd dengan command mosquitto_passwd -c /etc/mosquitto/passwd namauser.

3.3 Instalasi di Windows

  1. Kunjungi situs resmi https://mosquitto.org/download/
  2. Download installer Windows 64-bit (.exe)
  3. Jalankan installer, ikuti wizard hingga selesai
  4. Tambahkan folder instalasi Mosquitto ke system PATH (biasanya C:\Program Files\mosquitto\)
  5. Buka Command Prompt atau PowerShell, jalankan: mosquitto -v
PowerShell β€” Jalankan Mosquitto di Windows
# Jalankan Mosquitto broker dengan verbose logging
mosquitto -v

# Atau gunakan config file kustom
mosquitto -c "C:\mosquitto\mosquitto.conf" -v

# Test dari terminal terpisah
mosquitto_sub -h localhost -t "test/demo" -v
mosquitto_pub -h localhost -t "test/demo" -m "MQTT dari Windows!"

4. MQTT Client: Subscribe & Publish dengan Python

Python menyediakan library paho-mqtt yang memudahkan interaksi dengan MQTT broker. Library ini mendukung MQTT 3.1.1 dan 5.0, autentikasi, TLS/SSL, dan berbagai fitur lainnya.

4.1 Instalasi paho-mqtt

Terminal β€” Instalasi Library
# Instal paho-mqtt menggunakan pip
pip install paho-mqtt

# Verifikasi instalasi
python -c "import paho.mqtt.client as mqtt; print('paho-mqtt versi:', mqtt.__version__)"

4.2 Program Subscriber (Penerima Pesan)

Python β€” mqtt_subscriber.py
# mqtt_subscriber.py β€” Subscriber MQTT
# IoTHub - https://iothub.id

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

# === Konfigurasi ===
BROKER = "localhost"
PORT = 1883
TOPIC_SUBSCRIBE = "iothub/sensor/#"  # Wildcard: terima semua topik sensor

# === Callback saat koneksi berhasil ===
def on_connect(client, userdata, flags, rc, properties=None):
    if rc == 0:
        print("[OK] Terhubung ke MQTT broker!")
        # Subscribe ke topik
        client.subscribe(TOPIC_SUBSCRIBE)
        print(f"[INFO] Subscribed ke topik: {TOPIC_SUBSCRIBE}")
    else:
        print(f"[ERROR] Koneksi gagal! Kode error: {rc}")

# === Callback saat menerima pesan ===
def on_message(client, userdata, msg):
    try:
        payload = json.loads(msg.payload.decode("utf-8"))
        print(f"[DATA] Topik: {msg.topic}")
        print(f"       Suhu: {payload.get('suhu', 'N/A')} Β°C")
        print(f"       Kelembaban: {payload.get('kelembaban', 'N/A')} %")
        print(f"       Timestamp: {time.strftime('%H:%M:%S')}")
        print()
    except json.JSONDecodeError:
        print(f"[PESAN] Topik: {msg.topic} | Isi: {msg.payload.decode('utf-8')}")
    except Exception as e:
        print(f"[ERROR] Gagal memproses pesan: {e}")

# === Callback saat terputus ===
def on_disconnect(client, userdata, rc, properties=None):
    print(f"[WARN] Terputus dari broker (rc={rc}). Mencoba reconnect...")

# === Inisialisasi Client ===
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect

# Koneksi ke broker
print("Menghubungkan ke MQTT broker...")
client.connect(BROKER, PORT, keepalive=60)

# Mulai event loop (blocking)
# loop_forever() akan otomatis reconnect jika terputus
try:
    client.loop_forever()
except KeyboardInterrupt:
    print("\n[INFO] Subscriber dihentikan oleh user.")
    client.disconnect()

4.3 Program Publisher (Pengirim Pesan)

Python β€” mqtt_publisher.py
# mqtt_publisher.py β€” Publisher MQTT
# IoTHub - https://iothub.id

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

# === Konfigurasi ===
BROKER = "localhost"
PORT = 1883
TOPIC_PUBLISH = "iothub/sensor/ruang_tamu"
CLIENT_ID = "python_publisher_001"

# === Callback saat koneksi berhasil ===
def on_connect(client, userdata, flags, rc, properties=None):
    if rc == 0:
        print(f"[OK] Publisher terhubung ke broker! ID: {CLIENT_ID}")
    else:
        print(f"[ERROR] Koneksi gagal! rc={rc}")

# === Inisialisasi Client ===
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, CLIENT_ID)
client.on_connect = on_connect
client.connect(BROKER, PORT, keepalive=60)

# Jalankan loop di background agar bisa kirim data periodik
client.loop_start()

print(f"Mengirim data sensor ke topik: {TOPIC_PUBLISH}")
print("Tekan Ctrl+C untuk berhenti.\n")

try:
    while True:
        # Simulasi data sensor
        suhu = round(24.0 + random.uniform(0, 6), 1)
        kelembaban = round(50.0 + random.uniform(0, 30), 1)
        gas_ppm = random.randint(100, 400)

        # Buat payload JSON
        payload = {
            "suhu": suhu,
            "kelembaban": kelembaban,
            "gas_ppm": gas_ppm,
            "device": "esp32_lantai1",
            "uptime_detik": int(time.time()) % 86400
        }

        # Publish dengan QoS 1
        result = client.publish(
            TOPIC_PUBLISH,
            json.dumps(payload),
            qos=1
        )

        if result.rc == mqtt.MQTT_ERR_SUCCESS:
            print(f"[KIRIM] Suhu={suhu}Β°C | RH={kelembaban}% | Gas={gas_ppm}ppm")
        else:
            print(f"[ERROR] Gagal mengirim! rc={result.rc}")

        time.sleep(5)  # Kirim setiap 5 detik

except KeyboardInterrupt:
    print("\n[INFO] Publisher dihentikan oleh user.")
    client.loop_stop()
    client.disconnect()
    print("[OK] Koneksi ditutup.")
πŸ’‘ Tips Pengembangan

Untuk proyek nyata, pisahkan subscriber dan publisher ke file atau modul berbeda. Gunakan environment variable atau file config terpisah untuk menyimpan alamat broker, port, dan kredensial. Jangan hardcode informasi sensitif dalam kode.

5. MQTT dengan ESP32 (Arduino PubSubClient)

ESP32 dengan WiFi bawaan adalah kombinasi sempurna untuk proyek IoT berbasis MQTT. Library PubSubClient oleh Nick O'Leary adalah library MQTT paling populer untuk Arduino/ESP32, mendukung publish, subscribe, LWT, retained message, dan QoS 0 & 1.

5.1 Instalasi Library

  1. Buka Arduino IDE
  2. Menu Sketch β†’ Include Library β†’ Manage Libraries
  3. Cari "PubSubClient" oleh Nick O'Leary
  4. Klik Install

5.2 Program MQTT Publisher & Subscriber di ESP32

Diagram: Koneksi ESP32 dengan MQTT Broker
πŸ”Œ
ESP32
DHT11 (GPIO4)
LED (GPIO2) Β· Relay (GPIO5)
↔ WiFi TCP 1883
πŸ–₯️
MQTT Broker
Mosquitto Server
Port 1883 / 8883 (TLS)
β†’ Deliver
πŸ“Š
Subscriber
Dashboard / Mobile
Menerima data sensor
C++ β€” mqtt_esp32.ino
// =============================================
// ESP32 MQTT Publisher & Subscriber
// IoTHub - https://iothub.id
// =============================================

#include "WiFi.h"
#include "PubSubClient.h"

// === Konfigurasi WiFi ===
const char* WIFI_SSID = "NamaWiFiAnda";
const char* WIFI_PASS = "PasswordWiFi";

// === Konfigurasi MQTT ===
const char* MQTT_SERVER = "192.168.1.100";  // IP broker lokal
const int   MQTT_PORT   = 1883;
const char* CLIENT_ID   = "esp32_sensor_01";

// Topik publish (data sensor)
const char* TOPIC_DATA  = "rumah/lantai1/suhu";
// Topik subscribe (perintah remote)
const char* TOPIC_CMD   = "rumah/lantai1/cmd";

// === Pin ===
#define PIN_LED    2
#define PIN_RELAY  5

// === Objek ===
WiFiClient espClient;
PubSubClient mqtt(espClient);

// === Variabel ===
unsigned long lastKirim = 0;
const long INTERVAL = 10000;  // Kirim data setiap 10 detik

// === Callback saat menerima pesan ===
void callback(char* topic, byte* payload, unsigned int length) {
  // Konversi payload ke string
  String pesan = "";
  for (unsigned int i = 0; i < length; i++) {
    pesan += (char)payload[i];
  }

  Serial.print("[DITERIMA] Topik: ");
  Serial.print(topic);
  Serial.print(" | Pesan: ");
  Serial.println(pesan);

  // Handle perintah remote
  if (pesan == "LED_ON") {
    digitalWrite(PIN_LED, HIGH);
    Serial.println("[CMD] LED dinyalakan");
  } else if (pesan == "LED_OFF") {
    digitalWrite(PIN_LED, LOW);
    Serial.println("[CMD] LED dimatikan");
  } else if (pesan == "RELAY_ON") {
    digitalWrite(PIN_RELAY, HIGH);
    Serial.println("[CMD] Relay dinyalakan");
  } else if (pesan == "RELAY_OFF") {
    digitalWrite(PIN_RELAY, LOW);
    Serial.println("[CMD] Relay dimatikan");
  } else if (pesan == "STATUS") {
    // Kirim status device
    String status = "{\"device\":\"esp32_01\",\"status\":\"online\","
                    "\"led\":";
    status += digitalRead(PIN_LED) ? "true" : "false";
    status += ",\"relay\":";
    status += digitalRead(PIN_RELAY) ? "true" : "false";
    status += "}";
    mqtt.publish(TOPIC_DATA, status.c_str());
  }
}

// === Setup WiFi ===
void setupWiFi() {
  Serial.print("WiFi: Menghubungkan ke ");
  Serial.println(WIFI_SSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (++attempts > 40) {
      Serial.println(" [GAGAL! Restart]");
      ESP.restart();
    }
  }

  Serial.println();
  Serial.print("[OK] WiFi terhubung β€” IP: ");
  Serial.println(WiFi.localIP());
}

// === Setup MQTT ===
void setupMQTT() {
  mqtt.setServer(MQTT_SERVER, MQTT_PORT);
  mqtt.setCallback(callback);
  mqtt.setBufferSize(256);
}

// === Koneksi ke MQTT Broker ===
void hubungkanMQTT() {
  while (!mqtt.connected()) {
    Serial.print("MQTT: Menghubungkan...");

    // Buat LWT (Last Will and Testament)
    const char* lwtPayload = "{\"status\":\"offline\"}";

    if (mqtt.connect(CLIENT_ID, TOPIC_DATA, 1, true, lwtPayload)) {
      Serial.println(" [OK] Terhubung!");

      // Subscribe ke topik perintah
      mqtt.subscribe(TOPIC_CMD);
      Serial.print("Subscribed ke: ");
      Serial.println(TOPIC_CMD);

      // Publish status online
      mqtt.publish(TOPIC_DATA, "{\"status\":\"online\"}", true);
    } else {
      Serial.print(" [GAGAL, rc=");
      Serial.print(mqtt.state());
      Serial.println("] Coba lagi dalam 3 detik...");
      delay(3000);
    }
  }
}

// === Setup ===
void setup() {
  Serial.begin(115200);
  pinMode(PIN_LED, OUTPUT);
  pinMode(PIN_RELAY, OUTPUT);

  Serial.println("╔══════════════════════════════════╗");
  Serial.println("β•‘  ESP32 MQTT Sensor & Remote     β•‘");
  Serial.println("β•‘  IoTHub - https://iothub.id     β•‘");
  Serial.println("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•");

  setupWiFi();
  setupMQTT();
  hubungkanMQTT();
}

// === Loop ===
void loop() {
  if (!mqtt.connected()) {
    hubungkanMQTT();
  }
  mqtt.loop();

  unsigned long sekarang = millis();

  if (sekarang - lastKirim >= INTERVAL) {
    lastKirim = sekarang;

    // Simulasi data sensor (ganti dengan pembacaan sensor nyata)
    float suhu = 25.0 + (random(0, 100) / 10.0);
    float kelembaban = 55.0 + (random(0, 200) / 10.0);

    // Buat payload JSON
    char payload[128];
    snprintf(payload, sizeof(payload),
      "{\"suhu\":%.1f,\"kelembaban\":%.1f,"
      "\"led\":%s,\"relay\":%s}",
      suhu, kelembaban,
      digitalRead(PIN_LED) ? "true" : "false",
      digitalRead(PIN_RELAY) ? "true" : "false");

    // Publish data sensor
    if (mqtt.publish(TOPIC_DATA, payload)) {
      Serial.print("[KIRIM] ");
      Serial.println(payload);
    } else {
      Serial.println("[ERROR] Gagal publish!");
    }
  }
}
Output Serial Monitor: ╔══════════════════════════════════╗ β•‘ ESP32 MQTT Sensor & Remote β•‘ β•‘ IoTHub - https://iothub.id β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• WiFi: Menghubungkan ke RumahKu_IoT... WiFi: Menghubungkan ke RumahKu_IoT... [OK] MQTT: Menghubungkan... [OK] Terhubung! Subscribed ke: rumah/lantai1/cmd [KIRIM] {"suhu":27.3,"kelembaban":62.1,"led":false,"relay":false} [DITERIMA] Topik: rumah/lantai1/cmd | Pesan: LED_ON [CMD] LED dinyalakan [KIRIM] {"suhu":28.1,"kelembaban":58.4,"led":true,"relay":false}

6. Quality of Service (QoS 0, 1, 2)

Quality of Service (QoS) adalah mekanisme MQTT yang menentukan tingkat keandalan pengiriman pesan antara publisher dan subscriber melalui broker. Pemilihan QoS yang tepat sangat mempengaruhi performa, keandalan, dan penggunaan bandwidth sistem IoT.

6.1 QoS 0 β€” At Most Once (Fire and Forget)

Pesan dikirim sekali tanpa konfirmasi. Jika pesan hilang (jaringan terputus, broker penuh), pesan tidak akan dikirim ulang. Cocok untuk data yang berubah terus-menerus seperti sensor suhu real-time β€” data lama akan segera digantikan data baru.

6.2 QoS 1 β€” At Least Once (Acknowledged)

Pesan dikirim ulang sampai publisher menerima konfirmasi PUBACK dari broker. Pesan mungkin diterima lebih dari sekali (duplicate) karena mekanisme retry. Ini adalah level QoS paling umum digunakan.

6.3 QoS 2 β€” Exactly Once (Assured Delivery)

Mekanisme empat langkah handshake memastikan pesan diterima tepat satu kali. Proses: PUBLISH β†’ PUBREC β†’ PUBREL β†’ PUBCOMP. QoS 2 adalah yang paling lambat dan paling boros bandwidth, namun memberikan jaminan mutlak.

Aspek QoS 0 QoS 1 QoS 2
KeywordAt Most OnceAt Least OnceExactly Once
Jaminan Sampai❌ Tidakβœ… Yaβœ… Ya
Pesan Duplikatβ€”βœ… Mungkin❌ Tidak ada
Jumlah Pesan Jaringan12 (Publish + PubAck)4 (Handshake)
Kecepatan⚑ Paling cepat⚑ Cepat🐒 Paling lambat
Penggunaan MemoriSangat rendahRendahTinggi
Contoh KasusSuhu sensor real-timeNotifikasi alarmPerintah keselamatan
ℹ️ Kapan Pilih QoS Berapa?

Gunakan QoS 0 untuk data sensor yang terus diperbarui β€” data lama tidak relevan. Gunakan QoS 1 untuk notifikasi, alarm, atau data penting yang tidak boleh terlewat. Gunakan QoS 2 hanya untuk perintah kritis yang tidak boleh hilang DAN tidak boleh dieksekusi lebih dari sekali.

7. MQTT over TLS/SSL: Keamanan

MQTT default berjalan tanpa enkripsi (port 1883), yang berarti semua data termasuk kredensial dikirim dalam teks terbuka. Untuk lingkungan produksi, mengaktifkan TLS/SSL (port 8883) adalah langkah keamanan wajib untuk melindungi data dari intersepsi (man-in-the-middle attack).

7.1 Mengaktifkan TLS di Mosquitto

mosquitto.conf β€” Konfigurasi TLS/SSL
# === Konfigurasi Mosquitto dengan TLS ===

# Listener TLS pada port 8883
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
require_certificate false
tls_version tlsv1.2

# Listener tanpa TLS (untuk testing lokal saja)
listener 1883 localhost

# Autentikasi wajib saat TLS aktif
allow_anonymous false
password_file /etc/mosquitto/passwd

7.2 Membuat Sertifikat TLS

Terminal β€” Generate Sertifikat Self-Signed
# === Buat direktori sertifikat ===
mkdir -p /etc/mosquitto/certs
cd /etc/mosquitto/certs

# === 1. Buat Certificate Authority (CA) ===
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
  -subj "/CN=IoT-MQTT-CA/O=IoTHub"

# === 2. Buat Sertifikat Server ===
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/CN=mqtt.iothub.id/O=IoTHub"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 365

# === 3. Buat Sertifikat Client (opsional) ===
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
  -subj "/CN=esp32-sensor-01/O=IoTHub"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out client.crt -days 365

# === 4. Buat password file ===
mosquitto_passwd -c /etc/mosquitto/passwd username_publisher
mosquitto_passwd -b /etc/mosquitto/passwd username_subscriber secretpass123

# === 5. Restart Mosquitto ===
sudo systemctl restart mosquitto

7.3 Python Client dengan TLS

Python β€” mqtt_tls_client.py
# mqtt_tls_client.py β€” MQTT Client dengan TLS/SSL
# IoTHub - https://iothub.id

import paho.mqtt.client as mqtt
import ssl

# === Konfigurasi ===
BROKER = "mqtt.iothub.id"
PORT = 8883
USERNAME = "username_publisher"
PASSWORD = "rahasia123"
CA_CERT = "/etc/mosquitto/certs/ca.crt"
CLIENT_CERT = "/etc/mosquitto/certs/client.crt"
CLIENT_KEY = "/etc/mosquitto/certs/client.key"

# === Callback ===
def on_connect(client, userdata, flags, rc, properties=None):
    if rc == 0:
        print("[OK] Terhubung via TLS/SSL!")
        client.subscribe("rumah/sensor/#")
    else:
        print(f"[ERROR] Koneksi gagal: rc={rc}")

def on_message(client, userdata, msg):
    print(f"[DATA] {msg.topic}: {msg.payload.decode()}")

# === Inisialisasi ===
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, "secure_client")
client.username_pw_set(USERNAME, PASSWORD)

# Aktifkan TLS
client.tls_set(
    ca_certs=CA_CERT,
    certfile=CLIENT_CERT,
    keyfile=CLIENT_KEY,
    tls_version=ssl.PROTOCOL_TLSv1_2
)
client.tls_insecure_set(False)  # Verifikasi sertifikat

client.on_connect = on_connect
client.on_message = on_message

# Koneksi ke broker
print(f"Menghubungkan ke {BROKER}:{PORT} dengan TLS...")
client.connect(BROKER, PORT, keepalive=60)
client.loop_forever()

7.4 Tips Keamanan MQTT Tambahan

Langkah Keamanan Penjelasan Prioritas
Aktifkan TLS/SSLEnkripsi semua data komunikasi via port 8883πŸ”΄ Wajib
Gunakan AutentikasiSetiap client harus punya username & passwordπŸ”΄ Wajib
Nonaktifkan AnonymousSet allow_anonymous false di brokerπŸ”΄ Wajib
Gunakan ACLBatasi akses topik per client untuk isolasi data🟑 Penting
Disable Wildcard SubscribeHindari subscriber bisa akses semua topik🟑 Penting
Gunakan Client CertificateVerifikasi identitas perangkat via sertifikat X.509🟒 Opsional
Gunakan MQTT 5.0Fitur keamanan dan reason code yang lebih baik🟒 Opsional

8. MQTT vs HTTP vs WebSocket: Perbandingan

Memilih protokol komunikasi yang tepat adalah keputusan penting dalam desain sistem IoT. Berikut perbandingan mendalam antara MQTT, HTTP, dan WebSocket dari berbagai aspek.

8.1 Tabel Perbandingan Umum

⚑
MQTT
  • βœ… Publish-Subscribe async
  • βœ… Header hanya 2 byte
  • βœ… QoS 3 level (0, 1, 2)
  • βœ… Bandwidth sangat rendah
  • βœ… Retained messages
  • ❌ Perlu broker
  • βœ… Cocok: IoT sensor, telemetry
🌐
HTTP
  • ❌ Request-Response sync
  • ❌ Header ~800 byte
  • ❌ Tidak ada QoS
  • ❌ Bandwidth tinggi
  • βœ… Cache (ETag)
  • βœ… Universal & mudah debug
  • βœ… Cocok: REST API, web apps
πŸ”„
WebSocket
  • βœ… Full-duplex bidirectional
  • βœ… Header 6-14 byte
  • ❌ Tidak ada QoS
  • βœ… Latency sangat rendah
  • ❌ Tidak ada offline support
  • βœ… Browser-native
  • βœ… Cocok: Chat, live, gaming

8.2 Kapan Menggunakan MQTT?

8.3 Kapan Menggunakan HTTP?

8.4 Kapan Menggunakan WebSocket?

ℹ️ Kombinasi Protokol untuk IoT

Dalam sistem IoT production, ketiga protokol ini sering digunakan bersamaan. Contoh: MQTT untuk komunikasi sensor β†’ broker, WebSocket untuk broker β†’ dashboard real-time, dan HTTP REST untuk API management, provisioning, dan firmware update. Kuncinya adalah menggunakan protokol yang tepat untuk kebutuhan yang tepat.

9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang MQTT:

Pertanyaan 1: Istilah "publish-subscribe" dalam MQTT artinya?

a) Publisher harus tahu alamat subscriber untuk mengirim data
b) Subscriber mengirim data langsung ke publisher tanpa broker
c) Publisher mengirim pesan ke broker, lalu broker meneruskan ke subscriber yang sesuai
d) Semua client saling terhubung langsung secara peer-to-peer

Pertanyaan 2: Broker MQTT bertanggung jawab untuk apa?

a) Menerima pesan dari publisher, meneruskannya ke subscriber, dan mengelola sesi koneksi
b) Membaca data sensor secara langsung dari perangkat keras
c) Menyimpan data ke database SQL secara otomatis
d) Mengkonversi data analog ke digital

Pertanyaan 3: Wildcard # pada topik MQTT berfungsi untuk apa?

a) Menggantikan tepat satu level topik
b) Menggantikan satu atau lebih level topik (multi-level wildcard)
c) Membuat topik menjadi case-insensitive
d) Menonaktifkan enkripsi pada topik tertentu

Pertanyaan 4: Port default untuk MQTT dengan TLS/SSL adalah?

a) 1883
b) 8080
c) 443
d) 8883

Pertanyaan 5: QoS 2 dalam MQTT menjamin bahwa pesan akan diterima tepat sekali. Berapa banyak pesan jaringan yang dibutuhkan untuk satu pesan QoS 2?

a) 4 pesan (PUBLISH, PUBREC, PUBREL, PUBCOMP)
b) 1 pesan (hanya PUBLISH)
c) 2 pesan (PUBLISH, PUBACK)
d) 3 pesan (PUBLISH, PUBREC, PUBREL)
← Sebelumnya Panduan ESP8266 NodeMCU Selanjutnya β†’ Sensor DHT dengan ESP32