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.
Topik: "rumah/suhu"
Meneruskan pesan ke subscriber
Menerima dari topik
Fitur Utama MQTT
- Ringan: Header paket minimal hanya 2 byte β cocok untuk perangkat microcontroller dengan memori terbatas
- Publish-Subscribe: Publisher tidak perlu tahu siapa subscriber, begitu sebaliknya β memisahkan komponen secara efektif
- QoS (Quality of Service): Tiga level jaminan pengiriman pesan (0, 1, 2) sesuai kebutuhan keandalan
- Last Will and Testament (LWT): Broker otomatis memberitahu subscriber jika client terputus secara tidak normal
- Retained Messages: Broker menyimpan pesan terakhir di suatu topik sehingga subscriber baru langsung mendapatkan data terkini
- Last Clean Session: Opsi untuk menyimpan atau tidak menyimpan session client saat disconnect
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:
- Mosquitto β Broker open-source ringan dari Eclipse Foundation, cocok untuk pemula hingga produksi
- EMQX β Broker performa tinggi yang mampu menangani jutaan koneksi simultan
- HiveMQ β Broker enterprise dengan fitur cluster dan manajemen client lengkap
- AWS IoT Core β Layanan managed MQTT dari Amazon Web Services
- CloudMQTT β Broker managed berbasis Mosquitto untuk prototyping cepat
2.2 MQTT Client
Client adalah perangkat atau aplikasi yang terhubung ke broker. Client bisa berperan sebagai publisher, subscriber, atau keduanya sekaligus. Contoh client:
- Publisher: ESP32 dengan sensor yang mengirim data suhu ke broker
- Subscriber: Dashboard Grafana atau aplikasi mobile yang menerima data sensor
- Dual Role: ESP32 yang mengirim data sensor sekaligus menerima perintah dari remote
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.
# === 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 topik | rumah/+/suhu mencocokkan rumah/lantai1/suhu |
# | Menggantikan satu atau lebih level | rumah/# mencocokkan rumah/lantai1/ruang_tamu/suhu |
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:
- β Paling cepat & ringan
- β Tanpa konfirmasi
- β Pesan mungkin hilang
- β Tidak ada jaminan
- β Jaminan pesan sampai
- β Konfirmasi PUBACK
- β Pesan mungkin duplikat
- β 2 pesan jaringan
- β 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
# === 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!"
3.2 Konfigurasi Mosquitto
File konfigurasi Mosquitto terletak di /etc/mosquitto/mosquitto.conf. Berikut konfigurasi dasar untuk penggunaan lokal:
# === 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
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
- Kunjungi situs resmi https://mosquitto.org/download/
- Download installer Windows 64-bit (.exe)
- Jalankan installer, ikuti wizard hingga selesai
- Tambahkan folder instalasi Mosquitto ke system PATH (biasanya
C:\Program Files\mosquitto\) - Buka Command Prompt atau PowerShell, jalankan:
mosquitto -v
# 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
# 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)
# 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)
# 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.")
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
- Buka Arduino IDE
- Menu Sketch β Include Library β Manage Libraries
- Cari "PubSubClient" oleh Nick O'Leary
- Klik Install
5.2 Program MQTT Publisher & Subscriber di ESP32
LED (GPIO2) Β· Relay (GPIO5)
Port 1883 / 8883 (TLS)
Menerima data sensor
// =============================================
// 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!");
}
}
}
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.
- Kelebihan: Paling cepat, overhead paling kecil, hemat bandwidth
- Kekurangan: Tidak ada jaminan pengiriman, pesan bisa hilang
- Cocok untuk: Sensorι«ι’ update (suhu, kelembaban, GPS real-time)
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.
- Kelebihan: Jaminan pesan sampai, balance antara kecepatan dan keandalan
- Kekurangan: Pesan mungkin duplikat, perlu handle idempotency di subscriber
- Cocok untuk: Notifikasi, status update, data sensor yang perlu diketahui
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.
- Kelebihan: Pesan dijamin tepat sekali, tidak ada duplikat
- Kekurangan: Paling lambat, overhead paling besar, konsumsi memori broker lebih tinggi
- Cocok untuk: Perintah kritis (buka kunci, matikan mesin), transaksi finansial
| Aspek | QoS 0 | QoS 1 | QoS 2 |
|---|---|---|---|
| Keyword | At Most Once | At Least Once | Exactly Once |
| Jaminan Sampai | β Tidak | β Ya | β Ya |
| Pesan Duplikat | β | β Mungkin | β Tidak ada |
| Jumlah Pesan Jaringan | 1 | 2 (Publish + PubAck) | 4 (Handshake) |
| Kecepatan | β‘ Paling cepat | β‘ Cepat | π’ Paling lambat |
| Penggunaan Memori | Sangat rendah | Rendah | Tinggi |
| Contoh Kasus | Suhu sensor real-time | Notifikasi alarm | Perintah keselamatan |
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
# === 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
# === 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
# 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/SSL | Enkripsi semua data komunikasi via port 8883 | π΄ Wajib |
| Gunakan Autentikasi | Setiap client harus punya username & password | π΄ Wajib |
| Nonaktifkan Anonymous | Set allow_anonymous false di broker | π΄ Wajib |
| Gunakan ACL | Batasi akses topik per client untuk isolasi data | π‘ Penting |
| Disable Wildcard Subscribe | Hindari subscriber bisa akses semua topik | π‘ Penting |
| Gunakan Client Certificate | Verifikasi identitas perangkat via sertifikat X.509 | π’ Opsional |
| Gunakan MQTT 5.0 | Fitur 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
- β Publish-Subscribe async
- β Header hanya 2 byte
- β QoS 3 level (0, 1, 2)
- β Bandwidth sangat rendah
- β Retained messages
- β Perlu broker
- β Cocok: IoT sensor, telemetry
- β Request-Response sync
- β Header ~800 byte
- β Tidak ada QoS
- β Bandwidth tinggi
- β Cache (ETag)
- β Universal & mudah debug
- β Cocok: REST API, web apps
- β 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?
- Banyak perangkat kecil: Ratusan hingga ribuan sensor yang mengirim data periodik
- Bandwidth terbatas: Jaringan seluler, LoRa, atau koneksi satelit
- Baterai hemat daya: Perangkat yang harus bertahan berbulan-bulan dengan baterai
- Push data ke client: Server perlu mengirim update tanpa diminta
- Retained state: Subscriber baru langsung mendapat data terkini
8.3 Kapan Menggunakan HTTP?
- Interoperabilitas: Semua bahasa pemrograman dan framework mendukung HTTP
- REST API: CRUD operations untuk dashboard admin atau konfigurasi
- Simple request-response: Client hanya perlu mengambil data sesekali
- Debug mudah: Bisa diuji langsung dari browser atau Postman
8.4 Kapan Menggunakan WebSocket?
- Real-time bidirectional: Chat application, live score, trading platform
- Browser-based: Client adalah web browser yang tidak bisa maintain long-lived MQTT connection
- Game multiplayer: Update posisi pemain secara real-time
- Low latency required: Sama rendahnya dengan MQTT tetapi lebih umum di web
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: