mqttagent

MQTT Lua Agent
git clone https://git.instinctive.eu/mqttagent.git
Log | Files | Refs | README | LICENSE

commit 9c49acaed4653d2c0a6714df39399c52903bc3fd
parent a117cb30e7c06d8c0fbe1175d79ef5d682ca9bae
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Mon, 12 May 2025 17:50:29 +0000

Keep-alive ping is handled by mqttMonitor

No need to force boilerplate on all Lua scripts to handle it when a
goroutine is available to do so.
Diffstat:
Mmqttagent.go | 39++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/mqttagent.go b/mqttagent.go @@ -188,7 +188,17 @@ func processMsg(L *lua.LState, msg *mqttMessage) { } } -func mqttMonitor(client *mqtt.Client, toLua chan<- mqttMessage, id int) { +func mqttMonitor(client *mqtt.Client, toLua chan<- mqttMessage, id int, keepAliveS uint16) { + var tickerCh <-chan time.Time + var ticker *time.Ticker = nil + defer func() { + if ticker != nil { + ticker.Stop() + } + }() + + keepAlive := time.Duration(keepAliveS) * time.Second + for { <-client.Online() log.Println("Online client", id) @@ -199,7 +209,30 @@ func mqttMonitor(client *mqtt.Client, toLua chan<- mqttMessage, id int) { Message: []byte{}, } - <-client.Offline() + if keepAliveS > 0 { + ticker = time.NewTicker(keepAlive) + tickerCh = ticker.C + } + + online := true + + for online { + select { + case <-client.Offline(): + online = false + case <-tickerCh: + if err := client.Ping(nil); err != nil { + log.Println("Ping:", err) + } + } + } + + if ticker != nil { + ticker.Stop() + ticker = nil + tickerCh = nil + } + log.Println("Offline client", id) toLua <- mqttMessage{ Timestamp: float64(time.Now().UnixMicro()) * 1.0e-6, @@ -606,7 +639,7 @@ func newMqttClient(L *lua.LState) int { L.Push(lua.LString(err.Error())) return 2 } - go mqttMonitor(client, stateChanToLua(L), id) + go mqttMonitor(client, stateChanToLua(L), id, config.KeepAlive) go mqttRead(client, stateChanToLua(L), id) cfgMap[config] = mqttClientEntry{id: id, client: client}