Làm sao để dashboard IoT hiển thị đúng trạng thái online/offline của thiết bị theo thời gian thực? Trong bài này, bạn sẽ hiểu và áp dụng đúng Retained Message và Last Will của MQTT để theo dõi trạng thái thiết bị chính xác, không cần ping hay timeout phức tạp.
1) Bài toán thực tế: Vì sao dashboard IoT hay “nói dối”?
Rất nhiều dashboard IoT hiển thị:
- Thiết bị online dù đã mất điện
- Phải refresh trang mới biết thiết bị đã offline
- Không phân biệt được offline chủ động hay mất kết nối đột ngột
Nguyên nhân chính:
Chỉ dựa vào dữ liệu telemetry mà không có cơ chế status chuẩn.
Để giải quyết triệt để, MQTT đã cung cấp 2 tính năng sinh ra chỉ để làm việc này:
- Retained Message
- Last Will and Testament (LWT)
2) Retained Message là gì?
2.1 Khái niệm
Retained message là tin nhắn mà broker sẽ ghi nhớ lại giá trị cuối cùng của một topic.
Khi có client mới subscribe topic đó, broker gửi ngay message cuối cùng, không cần chờ publish mới.
2.2 Retained dùng để làm gì trong IoT?
- Hiển thị trạng thái hiện tại khi mở dashboard
- Không cần đợi thiết bị gửi lại
- Load UI rất nhanh
2.3 Ví dụ retained cho status online
Topic:
.../status
Payload:
{
"online": true,
"ts": 1768326000
}
Publish với retained = true.
👉 Dashboard mở lên là biết ngay thiết bị đang online hay offline.
3) Last Will and Testament (LWT) là gì?
3.1 Khái niệm
Last Will là tin nhắn mà client đăng ký trước với broker.
Nếu client mất kết nối bất thường (mất điện, treo, rớt mạng), broker sẽ tự động publish message này.
3.2 LWT dùng để làm gì?
- Phát hiện thiết bị offline đột ngột
- Không cần timeout dài
- Không cần polling
3.3 Ví dụ Last Will cho device offline
Topic:
.../status
Payload (offline):
{
"online": false,
"reason": "lost_connection"
}
👉 Broker tự gửi khi thiết bị rớt mạng.
4) Kết hợp Retained + Last Will (chuẩn bài)
Logic chuẩn
| Trường hợp | Ai publish | Retained |
|---|---|---|
| Device connect | Device | true |
| Device disconnect bất thường | Broker (LWT) | true |
| Dashboard subscribe | Broker | gửi retained |
👉 Không cần ping, không cần timeout.
5) Flow hoạt động end-to-end
- Device connect MQTT
- Device publish
{ online: true }(retained) - Device hoạt động bình thường
- Mất điện / treo
- Broker publish LWT
{ online: false }(retained) - Dashboard nhận ngay trạng thái offline
6) Code ví dụ ESP32 (rút gọn, dễ hiểu)
mqttClient.connect(
clientId,
mqttUser,
mqttPass,
statusTopic, // willTopic
1, // QoS
true, // retained
"{\"online\":false}" // willMessage
);
// Sau khi connect thành công
mqttClient.publish(statusTopic, "{\"online\":true}", true);
7) Mapping lên dashboard (chuẩn IoT Cloud)
- Status Card: Online / Offline (màu xanh – đỏ)
- Last Seen: từ timestamp trong status
- Event log: offline reason
👉 Dashboard phản ứng real-time, không cần reload.
8) Những sai lầm rất phổ biến
❌ Không dùng retained cho status
❌ Dùng retained cho telemetry
❌ Không cấu hình Last Will
❌ Dựa vào “lần cuối có telemetry” để đoán online/offline
9) Checklist triển khai đúng chuẩn
- Có topic
/statusriêng - Status publish với retained
- Last Will publish offline
- QoS 1 cho status
- Dashboard subscribe retained
10) Kết luận
Nếu bạn muốn dashboard IoT hiển thị đúng sự thật:
Retained + Last Will là bắt buộc, không phải tuỳ chọn.
Đây là nền tảng để xây dựng:
- Giám sát thiết bị
- Cảnh báo offline
- Hệ thống IoT chạy ổn định lâu dài
Bài tiếp theo trong series
Bài 7: MQTT có cần gửi liên tục không? (chọn tần suất theo mục tiêu)


