soypat / natiu-mqtt

A dead-simple, extensible MQTT implementation well suited for embedded systems.
MIT License
87 stars 4 forks source link
embedded embedded-systems go golang iot mqtt mqtt-client mqtt-embedded mqtt-protocol

Go Report Card GoDoc codecov

natiu-mqtt

A dead-simple, extensible and correct MQTT implementation.

Natiu: Means mosquito in the Guaraní language, a language spoken primarily in Paraguay. Commonly written as ñati'û or ñati'ũ.

Highlights

Goals

This implementation will have a simple embedded-systems implementation in the package top level. This implementation will be transport agnostic and non-concurrent. This will make it far easier to modify and reason about. The transport dependent implementations will have their own subpackage, so one package for TCP transport, another for UART, PPP etc.

Implementations

Examples

API subject to before v1.0.0 release.

Example use of Client

    // Create new client.
    client := mqtt.NewClient(mqtt.ClientConfig{
        Decoder: mqtt.DecoderNoAlloc{make([]byte, 1500)},
        OnPub: func(_ mqtt.Header, _ mqtt.VariablesPublish, r io.Reader) error {
            message, _ := io.ReadAll(r)
            log.Println("received message:", string(message))
            return nil
        },
    })

    // Get a transport for MQTT packets.
    const defaultMQTTPort = ":1883"
    conn, err := net.Dial("tcp", "127.0.0.1"+defaultMQTTPort)
    if err != nil {
        fmt.Println(err)
        return
    }

    // Prepare for CONNECT interaction with server.
    var varConn mqtt.VariablesConnect
    varConn.SetDefaultMQTT([]byte("salamanca"))
    ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
    err = client.Connect(ctx, conn, &varConn) // Connect to server.
    cancel()
    if err != nil {
        // Error or loop until connect success.
        log.Fatalf("connect attempt failed: %v\n", err)
    }

    // Ping forever until error.
    for {
        ctx, cancel := context.WithTimeout(context.Background(), time.Second)
        pingErr := client.Ping(ctx)
        cancel()
        if pingErr != nil {
            log.Fatal("ping error: ", pingErr, " with disconnect reason:", client.Err())
        }
        log.Println("ping success!")
    }

Why not just use paho?

Some issues with Eclipse's Paho implementation:

I found these issues after a 2 hour dev session. There will undoubtedly be more if I were to try to actually get it working...