256dpi / arduino-mqtt

MQTT library for Arduino
MIT License
1.01k stars 230 forks source link

Websockets support #303

Open PeeJay opened 1 year ago

PeeJay commented 1 year ago

There is another library based on this one (https://github.com/hideakitai/MQTTPubSubClient) that has websockets support, but I prefer using this library so I have ported over the websockets part.

https://github.com/PeeJay/arduino-mqtt/tree/websockets

At the moment I have used the same #define WEBSOCKETS approach to enable it, but I'm sure there is a better way if I thought about it like some sort of abstract class. If this is something you are interested in I can keep working on it.

Samtropic commented 1 year ago

Hi, I'm just trying to find an arduino library managing mqtt over websockets as my broker is set like that.

I already tried the hideakitai lib and yours but I can't connect to the broker on port 443. I'm stuck in the loop attempting connection client.connect() and an my debug reveals that this error is thrown : LWMQTT_MISSING_OR_WRONG_PACKET

I'm using M5stack core2. Could you provide a working example with one of the library you mentioned ?

PeeJay commented 1 year ago

Is it definitely websockets, and not just MQTT over SSL?. This is for an ESP32

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>
#include <WebSocketsClient.h>
#include <MQTT.h>

WebSocketsClient client;
MQTTClient mqtt;
WiFiMulti wiFiMulti;

void connect()
{
    if (wiFiMulti.run() != WL_CONNECTED)
    {
        while (wiFiMulti.run() != WL_CONNECTED)
        {
            delay(500);
            Serial.print(".");
        }

        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());
    }

    // connect to host with MQTT over WebSocket securely
    Serial.print("Connecting to mqtt server as ");
    String devId = "Arduino-" + String(ESP.getEfuseMac() >> 32, HEX);
    Serial.println(devId);
    client.beginSSL("server.com", 443, "/", "", "mqtt");
    while (!client.isConnected())
    {
        client.loop();
        delay(10);
    }

    // initialize mqtt client
    mqtt.connect(devId.c_str(), "username", "password");

    if (mqtt.connected())
    {
        Serial.println("Connected.");
    }
    else
    {
        Serial.println("Fail - retrying in 1 seconds]");
        delay(1000);
    }
}

void setup()
{
    Serial.begin(115200);

    wiFiMulti.addAP("wifiuser", "wifipass");
    mqtt.begin(client);
    connect();
}

void loop()
{
    static unsigned long lastMeasure = 0;
    static unsigned long measureTime = 1000 * 60;

    if ((millis() - lastMeasure) > measureTime)
    {
        lastMeasure = millis();

        // Check WiFi connection status
        if (WiFi.status() != WL_CONNECTED || !mqtt.connected())
        {
            Serial.println("Reconnecting...");
            connect();
        }

        // Send data on last sample
        mqtt.publish("hello/world", "data goes here");
    }

    mqtt.loop();
    delay(10);
}

Which gives the output

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13192
load:0x40080400,len:3028
entry 0x400805e4
Connecting to mqtt server as Arduino-3cab
Fail - retrying in 1 seconds]
Reconnecting...
Connecting to mqtt server as Arduino-3cab
Connected.

I've noticed that both libraries don't always connect on the first go, occasionally it takes a few retries. I'm not sure why.

Samtropic commented 1 year ago

Thank you very much, I finally managed to connect to my broker but using hideakitai library.

With yours, along with the example you provided, I wasn't able to compile because when invoking mqtt.begin(client) the code behind is waiting for a Client instance and not a WebSocketsClient 's one.

though i'm not sure about my headers management. Anyway you helped me a lot with your example ! And yes me too, the connection is failing at least once before establishing.