MQTT Protocol Integration for IoT Communication in Mobile Applications
MQTT is not just a "lightweight" protocol for IoT. It's publish/subscribe over TCP with delivery guarantees (QoS 0/1/2), persistent sessions, and "Last Will" messages. For mobile applications managing devices or monitoring sensors in real time, MQTT is the right choice. But mobile specifics (background, battery, unstable network) require careful tuning.
QoS and Its Real Cost
QoS 0 — fire and forget. Message sent, no confirmation, no duplicates. For displaying telemetry (temperature, GPS) — acceptable, losing one packet isn't critical.
QoS 1 — at least once. Broker confirms receipt with PUBACK. Client stores message until PUBACK received and retries if needed. Duplicates possible. For device commands (on/off) — usually sufficient.
QoS 2 — exactly once. Four-phase handshake: PUBLISH → PUBREC → PUBREL → PUBCOMP. Guarantees exactly one delivery. For financially significant commands or critical operations. Cost — doubled traffic, doubled latency.
On mobile, QoS 2 in background — problematic. Four-phase exchange requires stable connection over several RTTs. On connection loss mid-handshake, session "stalls" until reconnect. On iOS with background restrictions — almost guaranteed failure. Recommend QoS 1 + idempotent commands on device side.
Client Libraries and Their Pitfalls
Android: Eclipse Paho Android Service — de facto standard, but officially unsupported since 2021. Alternative — HiveMQ MQTT Client (com.hivemq:hivemq-mqtt-client), actively maintained, works with Kotlin Coroutines via kotlinx.coroutines. For MQTT 5 — HiveMQ only.
iOS: CocoaMQTT (Swift) or MQTTNio (SwiftNIO-based). CocoaMQTT simpler to configure, MQTTNio scales better for high-frequency streams.
Flutter: mqtt_client — popular library, supports MQTT 3.1.1. MQTT 5 support not yet. For WebSocket transport (MQTT over WSS, not TCP) — MqttServerClient vs MqttBrowserClient — use the right one.
React Native: no native MQTT. Options: react_native_mqtt (wrapper over native Paho for Android/iOS) or WebSocket transport with mqtt.js (works in RN without polyfills via WSS).
Connection Management on Mobile
Keep-alive interval (CONNECT packet, keepAlive field) — broker closes connection if no PINGREQ received within keepAlive * 1.5 seconds. Typical values for mobile: 30–60 seconds. Less — more traffic and battery drain. More — risk of missing disconnection timely.
Last Will Message: when registering connection, specify willTopic and willMessage (e.g., {"status":"offline"}). If connection breaks abruptly (without DISCONNECT), broker automatically publishes this message. Other clients' UI sees device offline without extra logic.
Persistent Session (cleanSession: false in MQTT 3.x, sessionExpiryInterval > 0 in MQTT 5): broker stores QoS 1/2 message queue for client while offline. Upon reconnect, client receives accumulated messages. Critical for IoT commands that must reach device even during temporary disconnection. Keep clientId permanent — mandatory for persistent session to work.
TLS and Authentication
For production: MQTT over TLS (mqtts://, port 8883). Mutual TLS authentication (mTLS) — standard for IoT devices, but for mobile client usually sufficient: username/password + server TLS certificate.
On Android: store credentials in EncryptedSharedPreferences. On iOS: Keychain. Don't hardcode broker URL and credentials in code — use remote config or sealed secrets in CI.
Timeline for integrating MQTT into existing mobile application — 1–3 weeks depending on topic schema complexity and offline requirements.







