Tutoriais de IoT

Bibliotecas Cliente MQTT: Como Escolher a Certa para Cada Linguagem

Uma comparação prática das bibliotecas cliente MQTT mantidas para Python, JavaScript, Go, Java, C#, Rust, C, sistemas embarcados e mobile, com um exemplo mínimo de conexão e publish para cada uma, testado no servidor MQTT público broker.connectmq.com.

Janelas de editor de código em várias linguagens de programação conectadas a um único broker, ilustrando bibliotecas cliente MQTT
Rode isso no seu próprio broker MQTTTenha um broker MQTT privado e gerenciado no plano Free e comece com exemplos de código prontos.
Teste grátis Exemplos de código Sem cartão de crédito

Escolher entre bibliotecas cliente MQTT é a primeira decisão de engenharia de verdade em qualquer projeto MQTT, e uma escolha errada aparece mais tarde na forma de bugs de reconexão, recursos do MQTT 5 ausentes ou um event loop bloqueado. Este guia compara as opções mantidas para Python, JavaScript, Go, Java, C#, Rust, C, microcontroladores e mobile, e traz para cada uma um exemplo mínimo que se conecta ao broker.connectmq.com, o servidor MQTT público (gratuito) do ConnectMQ. Ao final, você saberá qual biblioteca combina com a sua stack e o que verificar antes de se comprometer com ela.

O Que uma Biblioteca Cliente MQTT Faz de Fato

Uma biblioteca cliente MQTT esconde o protocolo binário atrás de poucas chamadas: connect, subscribe, publish, disconnect. Por baixo dos panos ela faz muito mais, e é nessas tarefas ocultas que as bibliotecas se diferenciam:

  • Codificação e decodificação de pacotes para MQTT 3.1.1 e, nas bibliotecas melhores, propriedades do MQTT 5.0 como reason codes, expiração de mensagens e user properties.
  • Pings de keep-alive para que o broker saiba que a conexão está saudável.
  • Máquinas de estado de QoS que armazenam mensagens QoS 1 e QoS 2 em trânsito e as reenviam após uma reconexão.
  • Lógica de reconexão com backoff, além de reassinar os topics quando a sessão não foi persistida.
  • Tratamento de transporte para TCP, TLS e WebSocket.
  • Integração com threads ou async no seu runtime: uma thread em segundo plano, um event loop, goroutines ou callbacks.

Uma biblioteca que acerta a codificação do protocolo mas lida mal com reconexões passa em todas as demos e falha em campo, por exemplo no gateway celular de uma fazenda ou de uma mineradora. Tenha isso em mente ao ler a comparação abaixo. Se o lado do broker ainda não estiver claro, leia primeiro o que um broker MQTT faz; todas as bibliotecas aqui são apenas clientes de um broker.

Como Avaliar Bibliotecas Cliente MQTT

Use este checklist antes de adotar qualquer biblioteca, seja qual for a linguagem:

  1. Manutenção. Observe os lançamentos recentes e como as issues são tratadas. O MQTT em si é estável, mas stacks de TLS, runtimes e plataformas mudam o tempo todo.
  2. Versão do protocolo. Você precisa de MQTT 5? Assinaturas compartilhadas, expiração de mensagens, request/response e reason codes detalhados só existem nele.
  3. Transportes. Navegadores precisam de WebSocket; redes corporativas restritas muitas vezes exigem WSS em portas no estilo da 443; dispositivos geralmente usam TLS na 8883.
  4. Modelo de concorrência. Baseado em callbacks, em threads ou em async/await. Escolha o que combina com o resto do seu código, não o que parece mais curto em um README.
  5. Reconexão e buffer offline. Ela reconecta automaticamente? Enfileira publishes enquanto está offline, e essa fila tem limite?
  6. Persistência de mensagens em trânsito. Só em memória ou em arquivo? Isso importa para QoS 1 e 2 entre reinícios do processo.
  7. Footprint. Em microcontroladores, RAM e flash decidem tudo; em servidores, raramente importam.
  8. Licença. As bibliotecas mais populares usam EPL/EDL, MIT ou Apache 2.0, mas confira antes de lançar um produto comercial.

Bibliotecas Cliente MQTT em Resumo

Linguagem / plataforma Biblioteca MQTT 5 Modelo Indicada para
Python paho-mqtt 2.x Sim Thread em segundo plano ou loop manual Scripts, gateways, Raspberry Pi
Python aiomqtt Sim asyncio Serviços assíncronos, backends FastAPI
JavaScript / TypeScript MQTT.js 5.x Sim Event emitter, promises Node.js e navegadores (WebSocket)
Go Eclipse Paho Go (paho.mqtt.golang) Não (3.1.1) Tokens, goroutines Serviços 3.1.1 maduros
Go Eclipse Paho paho.golang Sim Baseado em context Novos serviços MQTT 5
Java / Kotlin Eclipse Paho Java (mqttv3, mqttv5) Sim (pacote v5) Clientes síncronos e assíncronos Backends JVM, Android
Java / Kotlin HiveMQ MQTT Client Sim Bloqueante, assíncrono, reativo Stacks JVM reativas
C# / .NET MQTTnet Sim async/await ASP.NET Core, MAUI, Unity
Rust rumqttc Sim async (tokio) ou síncrono Serviços de borda, gateways
C Eclipse Paho C, libmosquitto Sim Síncrono e assíncrono Dispositivos Linux, aplicações nativas
Arduino / ESP32 PubSubClient, AsyncMqttClient Não (3.1.1) Baseado em loop / callbacks assíncronos Microcontroladores
ESP-IDF esp-mqtt Sim Event handler Firmware ESP32 de produção
Swift CocoaMQTT Sim Delegate / closures Apps iOS e macOS
Dart / Flutter mqtt_client Não (3.1.1) Streams Mobile multiplataforma

A tabela reflete os recursos documentados das bibliotecas no momento em que este texto foi escrito. Sempre confirme nas notas de versão atuais de cada projeto, porque o suporte a MQTT 5, em especial, vem chegando em etapas. A página do projeto Eclipse Paho em eclipse.dev/paho é um bom ponto de partida para a família Paho.

Python: paho-mqtt e aiomqtt

O paho-mqtt é a escolha padrão em Python e funciona em quase todo lugar, de um Raspberry Pi a um contêiner. A versão 2.x introduziu uma mudança incompatível: é obrigatório informar uma versão da API de callbacks, e os callbacks v2 recebem reason codes e properties. A maioria dos relatos de "não funciona" vem de copiar exemplos 1.x para uma instalação 2.x, o que é explicado em detalhes em a correção do CallbackAPIVersion no paho-mqtt 2.0.

import uuid
import paho.mqtt.client as mqtt

TOPIC = "connectmq/demo/k3x8p1/libs/python"

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(TOPIC, qos=1)
    client.publish(TOPIC, "hello from paho-mqtt", qos=1)

def on_message(client, userdata, msg):
    print(msg.topic, msg.payload.decode())

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=f"libs-py-{uuid.uuid4().hex[:8]}",
    protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=30)
client.loop_forever()

O aiomqtt encapsula o paho em uma API asyncio idiomática com async with e async for. Se o seu serviço já roda um event loop, use-o em vez de misturar threads e corrotinas. Os passo a passo completos estão no nosso tutorial de paho-mqtt em Python e no guia de aiomqtt com asyncio.

JavaScript e TypeScript: MQTT.js

O MQTT.js é a biblioteca de fato para Node.js e para o navegador, traz tipos TypeScript e suporta MQTT 5. No Node.js ele se conecta via TCP ou TLS; no navegador usa WebSocket, então o esquema da URL é a única coisa que muda.

import mqtt from "mqtt";

const clientId = "libs-js-" + Math.random().toString(16).slice(2, 10);
const topic = "connectmq/demo/k3x8p1/libs/javascript";

// Node.js: mqtts://broker.connectmq.com:8883
// Navegador: wss://broker.connectmq.com:8084/mqtt
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId,
  protocolVersion: 5,
});

client.on("connect", async () => {
  await client.subscribeAsync(topic, { qos: 1 });
  await client.publishAsync(topic, "hello from MQTT.js", { qos: 1 });
});

client.on("message", (t, payload) => console.log(t, payload.toString()));
client.on("error", (err) => console.error(err.message));

O MQTT.js reconecta automaticamente por padrão (reconnectPeriod controla o intervalo). No navegador, lembre-se de que uma página HTTPS só pode abrir conexões wss://. Padrões específicos de frameworks estão em MQTT.js com Node.js e MQTT no navegador com JavaScript.

Go: Eclipse Paho

Go tem dois projetos Eclipse. O paho.mqtt.golang é o cliente MQTT 3.1.1 consolidado, usado em muitíssimos serviços de produção. O paho.golang é a implementação mais nova de MQTT 5, com um pacote autopaho que gerencia a reconexão para você. Para um novo projeto MQTT 5, comece pelo paho.golang; para ampla compatibilidade com 3.1.1 e a maior base de exemplos, o cliente clássico continua sendo uma escolha sólida.

package main

import (
	"crypto/tls"
	"fmt"
	"math/rand"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

func main() {
	topic := "connectmq/demo/k3x8p1/libs/go"
	opts := mqtt.NewClientOptions().
		AddBroker("tls://broker.connectmq.com:8883").
		SetClientID(fmt.Sprintf("libs-go-%06d", rand.Intn(1000000))).
		SetTLSConfig(&tls.Config{MinVersion: tls.VersionTLS12}).
		SetAutoReconnect(true)

	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	client.Subscribe(topic, 1, func(_ mqtt.Client, m mqtt.Message) {
		fmt.Printf("%s %s\n", m.Topic(), m.Payload())
	}).Wait()

	client.Publish(topic, 1, false, "hello from Go").Wait()
	time.Sleep(2 * time.Second)
	client.Disconnect(250)
}

Veja como construir um cliente MQTT em Go para encerramento gracioso e payloads estruturados.

Java e Kotlin: Paho e HiveMQ Client

O Eclipse Paho Java oferece dois pacotes: org.eclipse.paho.client.mqttv3 para MQTT 3.1.1 e org.eclipse.paho.mqttv5.client para MQTT 5. O HiveMQ MQTT Client é uma alternativa com APIs bloqueante, assíncrona e reativa, que se encaixa bem em bases de código com Reactor ou RxJava. Ambos também rodam no Android, e é por isso que apps Kotlin costumam usá-los diretamente.

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.util.UUID;

public class LibsJava {
    public static void main(String[] args) throws Exception {
        String topic = "connectmq/demo/k3x8p1/libs/java";
        String clientId = "libs-java-" + UUID.randomUUID().toString().substring(0, 8);

        MqttClient client = new MqttClient("ssl://broker.connectmq.com:8883",
                clientId, new MemoryPersistence());
        MqttConnectOptions options = new MqttConnectOptions();
        options.setAutomaticReconnect(true);
        options.setCleanSession(true);
        client.connect(options);

        client.subscribe(topic, 1, (t, msg) ->
                System.out.println(t + " " + new String(msg.getPayload())));
        client.publish(topic, "hello from Paho Java".getBytes(), 1, false);

        Thread.sleep(2000);
        client.disconnect();
        client.close();
    }
}

Quem usa Spring Boot normalmente encapsula isso no Spring Integration; os padrões estão no nosso guia de cliente MQTT em Java e no tutorial de MQTT no Android com Kotlin.

C# e .NET: MQTTnet

O MQTTnet é a biblioteca padrão do .NET e suporta MQTT 5, TLS e WebSocket. É totalmente assíncrono e se encaixa em hosted services do ASP.NET Core, apps .NET MAUI e Unity. Atenção às diferenças entre as versões principais: a versão 5 renomeou a factory para MqttClientFactory, enquanto a versão 4 usa MqttFactory. O exemplo é para a versão 5.

using MQTTnet;
using MQTTnet.Formatter;

var topic = "connectmq/demo/k3x8p1/libs/csharp";
var factory = new MqttClientFactory();
using var client = factory.CreateMqttClient();

client.ApplicationMessageReceivedAsync += e =>
{
    Console.WriteLine($"{e.ApplicationMessage.Topic} {e.ApplicationMessage.ConvertPayloadToString()}");
    return Task.CompletedTask;
};

var options = new MqttClientOptionsBuilder()
    .WithTcpServer("broker.connectmq.com", 8883)
    .WithClientId($"libs-cs-{Guid.NewGuid():N}"[..16])
    .WithProtocolVersion(MqttProtocolVersion.V500)
    .WithTlsOptions(o => o.UseTls())
    .Build();

await client.ConnectAsync(options);
await client.SubscribeAsync(factory.CreateSubscribeOptionsBuilder()
    .WithTopicFilter(topic).Build());

await client.PublishAsync(new MqttApplicationMessageBuilder()
    .WithTopic(topic).WithPayload("hello from MQTTnet").Build());

await Task.Delay(2000);
await client.DisconnectAsync();

O cliente de baixo nível do MQTTnet não reconecta sozinho, então envolva a conexão em um loop ou em um background service. O tutorial de MQTTnet mostra um padrão resiliente com hosted service.

Rust: rumqttc

O rumqttc é o cliente Rust mais usado. Ele separa o handle do cliente de um event loop que você consulta (poll), o que dá controle explícito sobre back-pressure. Existem módulos tanto para MQTT 3.1.1 quanto para MQTT 5.

use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS};
use std::time::Duration;

#[tokio::main]
async fn main() {
    let topic = "connectmq/demo/k3x8p1/libs/rust";
    let mut opts = MqttOptions::new("libs-rust-k3x8p1", "broker.connectmq.com", 1883);
    opts.set_keep_alive(Duration::from_secs(30));

    let (client, mut eventloop) = AsyncClient::new(opts, 10);
    client.subscribe(topic, QoS::AtLeastOnce).await.unwrap();
    client.publish(topic, QoS::AtLeastOnce, false, "hello from rumqttc").await.unwrap();

    loop {
        match eventloop.poll().await {
            Ok(Event::Incoming(Packet::Publish(p))) => {
                println!("{} {}", p.topic, String::from_utf8_lossy(&p.payload));
            }
            Ok(_) => {}
            Err(e) => {
                eprintln!("connection error: {e}");
                tokio::time::sleep(Duration::from_secs(2)).await;
            }
        }
    }
}

Chamar o poll do event loop de novo após um erro é a forma como o rumqttc reconecta. O TLS exige uma das suas feature flags de TLS; o guia de rumqttc cobre essa configuração.

C e Sistemas Embarcados: Paho C, libmosquitto, PubSubClient, esp-mqtt

Para aplicações Linux nativas, o Eclipse Paho C oferece APIs síncronas e assíncronas com suporte a MQTT 5, e a libmosquitto é uma alternativa pequena e testada em batalha do projeto Mosquitto.

#include <stdio.h>
#include <string.h>
#include "MQTTClient.h"

int main(void) {
    MQTTClient client;
    MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
    MQTTClient_message msg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    const char *topic = "connectmq/demo/k3x8p1/libs/c";
    char payload[] = "hello from Paho C";

    MQTTClient_create(&client, "tcp://broker.connectmq.com:1883", "libs-c-k3x8p1",
                      MQTTCLIENT_PERSISTENCE_NONE, NULL);
    opts.keepAliveInterval = 30;
    opts.cleansession = 1;

    if (MQTTClient_connect(client, &opts) != MQTTCLIENT_SUCCESS) {
        fprintf(stderr, "connect failed\n");
        return 1;
    }

    msg.payload = payload;
    msg.payloadlen = (int)strlen(payload);
    msg.qos = 1;
    msg.retained = 0;
    MQTTClient_publishMessage(client, topic, &msg, &token);
    MQTTClient_waitForCompletion(client, token, 10000L);

    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return 0;
}

Em microcontroladores, os trade-offs mudam. O PubSubClient é minúsculo e simples, mas suporta apenas MQTT 3.1.1, publica em QoS 0 e tem um buffer de pacotes padrão de 256 bytes que você precisa aumentar com setBufferSize() para payloads JSON. O AsyncMqttClient adiciona publicação em QoS 1 e 2 com um design não bloqueante. Para firmware ESP32 de produção, o componente esp-mqtt da Espressif no ESP-IDF suporta MQTT 5, TLS e WebSocket e é mantido pelo próprio fabricante do chip. Comece pelo tutorial ESP32 MQTT para ter código Arduino funcionando, e pelo Paho MQTT C para dispositivos Linux.

Mobile: Swift, Kotlin, Flutter e React Native

Clientes mobile enfrentam uma restrição que servidores não têm: o sistema operacional suspende apps em segundo plano e encerra sockets ociosos. Seja qual for a biblioteca escolhida, planeje reconexões frequentes, use sessões persistentes ou retained messages para recuperar o atraso e use notificações push para tudo o que precisa chegar a um celular em repouso.

  • iOS / macOS: o CocoaMQTT suporta MQTT 5, TLS e WebSocket. Veja MQTT no iOS com Swift.
  • Android: Paho Java ou o cliente HiveMQ a partir de Kotlin, de preferência dentro de um componente ciente do ciclo de vida.
  • Flutter: o mqtt_client cobre alvos de servidor e navegador a partir de uma única base de código Dart. Veja o tutorial de MQTT com Flutter.
  • React Native: MQTT.js sobre WebSocket é o caminho mais comum, com alguns polyfills. Veja MQTT com React Native.

Armadilhas que Parecem Bugs da Biblioteca

A maioria dos problemas atribuídos a uma biblioteca são, na verdade, problemas de configuração ou de projeto. Verifique estes primeiro:

Sintoma Causa real Solução
Loop constante de conexão/desconexão Dois processos compartilham um client ID Gere IDs únicos; o broker derruba a sessão mais antiga
Nenhuma mensagem após reconectar Clean session sem reassinatura Reassine no callback de conexão, não apenas uma vez na inicialização
O event loop congela Trabalho bloqueante dentro de um callback de mensagem Repasse o trabalho para uma fila, um pool de threads ou uma task assíncrona
Payloads grandes descartados silenciosamente Buffer do cliente ou limite de tamanho do broker Aumente o buffer do cliente; respeite os limites do broker
Handshake TLS falha no dispositivo CA raiz ausente ou relógio errado Instale o pacote de CAs e sincronize a hora via NTP antes de conectar
Duplicatas em QoS 1 Comportamento esperado de entrega "pelo menos uma vez" Torne os handlers idempotentes; veja níveis de QoS MQTT explicados

O tratamento de reconexão merece atenção especial em Python; o guia de reconexão do paho-mqtt explica as configurações de backoff. Para uma abordagem sistemática de verificação de um cliente antes de lançá-lo, leia testando clientes MQTT, e mantenha à mão os exemplos de mosquitto_pub e mosquitto_sub como um segundo cliente independente durante a depuração.

Migrando do Servidor MQTT Público para o Seu Próprio Broker

Todos os exemplos acima usam o servidor MQTT público anônimo, que é perfeito para comparar bibliotecas lado a lado: rode o subscriber Python, publique a partir de Go e veja a mensagem chegar. O servidor MQTT público, porém, é compartilhado, serve para testes e protótipos e pode ser lido por qualquer pessoa, então clientes de produção precisam de credenciais e de um broker isolado.

A ConnectMQ é um broker MQTT gerenciado que funciona com todas as bibliotecas deste guia, porque fala MQTT 3.1.1 e 5.0 padrão sobre TCP 1883, TLS 8883, WebSocket 8083 e WebSocket seguro 8084 (caminho /mqtt). Ao criar um broker no portal, você recebe um nome de usuário, uma senha e um client ID. Adaptar qualquer exemplo acima é uma mudança de três linhas, mostrada aqui para o paho-mqtt:

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()

A ConnectMQ vincula os client IDs às credenciais emitidas, então use o ID gerado exatamente como fornecido. Se você ainda está decidindo como hospedar seu broker, nosso guia sobre o cenário de broker MQTT na nuvem compara as opções serverless, dedicada e na sua própria nuvem.

Conecte Qualquer Biblioteca MQTT à ConnectMQ

Escolha a biblioteca que combina com a sua stack, rode o exemplo dela no broker.connectmq.com e, quando chegar a hora de ter topics privados, crie um broker gratuito em app.connectmq.com. O plano Serverless (Free) não exige cartão de crédito e oferece até 25 conexões, QoS até 1 e mensagens de 256 KB, o que é mais do que suficiente para construir e testar clientes em várias linguagens ao mesmo tempo.

Perguntas frequentes

Qual é a melhor biblioteca cliente MQTT?

Não existe uma única melhor; a escolha certa é a biblioteca mantida que combina com a sua linguagem e com o seu modelo de concorrência. paho-mqtt para Python, MQTT.js para JavaScript, MQTTnet para .NET e Paho ou rumqttc para Go e Rust são os padrões mais comuns e bem suportados.

Todas as bibliotecas cliente MQTT suportam MQTT 5?

Não. Várias bibliotecas populares, incluindo a PubSubClient para Arduino e o cliente Paho Go clássico, implementam apenas MQTT 3.1.1. Se você precisa de assinaturas compartilhadas, expiração de mensagens ou reason codes, confirme o suporte a MQTT 5 antes de adotar uma biblioteca.

Clientes escritos em linguagens diferentes conseguem conversar entre si?

Sim. O broker roteia bytes, não objetos de linguagem, então um publisher em Python e um subscriber em C# se comunicam normalmente, desde que concordem sobre os topics e o formato do payload. JSON é o formato comum mais fácil para começar.

Qual biblioteca devo usar no navegador?

MQTT.js sobre WebSocket seguro é a escolha padrão. Conecte-se a wss://broker.connectmq.com:8084/mqtt, porque navegadores não conseguem abrir sockets TCP puros e páginas HTTPS bloqueiam conexões WebSocket inseguras.

Por que meu cliente funciona no servidor MQTT público, mas não em um broker privado?

Geralmente faltam credenciais, o client ID não corresponde ao emitido ou o TLS não está ativado. Verifique o reason code do CONNACK informado pela sua biblioteca; ele indica exatamente qual desses itens está errado.

Artigos relacionados

Melhores Ferramentas CLI MQTT para Testes, Scripts e Depuração

Uma comparação prática entre mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, a CLI do MQTT.js, curl e mqttui, com o mesmo teste rodando no broker.connectmq.com, para você escolher a ferramenta certa para scripts e depuração.

9 min de leitura

Todos os artigos →

Seu broker MQTT privado está a poucos cliques de distância

Crie uma conta, receba as credenciais do seu broker e conecte seu primeiro dispositivo — sem servidores para instalar, atualizar ou escalar.