猿问

如何有效地设置MQTT的连接超时?

我想确保我的程序在无法连接到MQTT服务器时崩溃。为此,我将ConnectTimeout设置为10秒,但是当连接到不存在的服务器(名称不存在)时,对MQTT的调用挂起。


package main


import (

    "fmt"

    "time"


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

)


func main() {

    timeout, _ := time.ParseDuration("10s");

    opts := mqtt.NewClientOptions()

    opts.AddBroker("tcp://this.does.not.resolve.example.coooom:1883")

    opts.SetClientID("monitor")

    opts.SetOrderMatters(false)

    opts.SetConnectRetry(true)

    opts.SetConnectTimeout(timeout)

    client := mqtt.NewClient(opts)

    if token := client.Connect(); token.Wait() && token.Error() != nil {

        panic(fmt.Sprintf("cannot connect to MQTT: %v", token.Error()))

    }

}

如何正确设置超时?


HUWWW
浏览 1739回答 2
2回答

料青山看我应如是

来自 SetConnectRetry 的文档:SetConnectRetry 设置连接函数在发生故障时是否会自动重试连接(如果为 true,则 Connect 函数返回的令牌在连接启动或取消之前不会完成)如果 ConnectRetry 为 true,则应在 OnConnect 处理程序中请求订阅 如果设置为 TRUE,则允许在建立连接之前发布消息。因此,何时将重试,直到成功或您停止它。不会尝试确定错误是否是永久性的,因为这非常困难(例如,无法解决可能是由于互联网连接丢失)。SetConnectRetry(true)Connect()this.does.not.resolve.example.coooom注意:有一个单独的选项,用于控制断开的连接(在成功建立初始连接后)是否会导致客户端自动重新建立连接。SetAutoReconnect值得注意的是,添加该选项的主要原因是允许用户在连接启动之前发布消息(当建立连接时,它们将自动发送)。这个想法是,您应该能够调用然后使用库,而不必担心网络状态(显然,如果网络出现故障,您将不会收到消息!ConnectRetryConnectSetConnectTimeout文档在如何与以下各项交互方面可能并不像它们应该的那样清晰:SetConnectRetrySetConnectTimeout 限制客户端在超时之前尝试打开与 MQTT 服务器的连接时将等待的时间。持续时间 0 永远不会超时。默认值为 30 秒。目前仅在 TCP/TLS 连接上运行。因此,这控制了我们将等待单个连接尝试完成的时间。每次尝试连接时将使用此间隔(每次尝试时重新开始)。没有类型设置。SetConnectRetry (true)RetryConnectionsFor来自自我回答:...连接正确失败(并且,如果连接断开,客户端仍将重新连接)一旦调用了选项,就无法更改选项(获取选项的副本)。它之所以这样做,是因为在操作过程中更改选项将导致不可预测的结果(例如,如果您在调用后调用,则结果将取决于调用是否已完成,这是不可预测的)。NewClient(o *ClientOptions)NewClientopts.SetConnectRetry(true)ConnectConnect我不太确定你所说的“确保我的程序崩溃,如果它无法连接到MQTT服务器”是什么意思,但我使用的方法是如下(用适当的操作代替语句) - 请注意,我还没有编译/测试这个:fmt.PrintLnpackage mainimport (    "fmt"    mqtt "github.com/eclipse/paho.mqtt.golang"    "time")func main() {    timeout, _ := time.ParseDuration("10s")    opts := mqtt.NewClientOptions()    opts.AddBroker("tcp://this.does.not.resolve.example.coooom:1883")    opts.SetClientID("monitor")    opts.SetOrderMatters(false)    opts.SetAutoReconnect(true).SetMaxReconnectInterval(10 * time.Second)    opts.SetConnectRetry(true)    opts.SetConnectTimeout(timeout)    client := mqtt.NewClient(opts)    token := client.Connect()    go func(token mqtt.Token) {    for {        done := token.WaitTimeout(1 * time.Minute)        if done {            if token.Error() != nil {                fmt.Println("Connection permanently failed (most probably due to call to Disconnect)", token.Error())            } else {                fmt.Println("Connection established")            }            return // We are done!        }        fmt.Println("Async MQTT Connection still trying (there could be an issue!)")        // Can call `client.Disconnect()` to cancel connection if you want to cancel the connection attempts    }    }(token)    // Do some stuff - you can publish messages and the library will send them when the connection comes up}

临摹微笑

opts.SetConnectRetry(true)似乎将连接放在循环中(没有任何错误消息)。通过将代码更改为 ...package mainimport (    "fmt"    "time"    mqtt "github.com/eclipse/paho.mqtt.golang")func main() {    timeout, _ := time.ParseDuration("10s");    opts := mqtt.NewClientOptions()    opts.AddBroker("tcp://this.does.not.resolve.example.coooom:1883")    opts.SetClientID("monitor")    opts.SetOrderMatters(false)    opts.SetConnectTimeout(timeout)    client := mqtt.NewClient(opts)    if token := client.Connect(); token.Wait() && token.Error() != nil {        panic(fmt.Sprintf("cannot connect to MQTT: %v", token.Error()))    }    opts.SetConnectRetry(true)}...连接正确失败(并且,如果连接断开,客户端仍将重新连接)编辑:我不认为在连接尝试后移动会使其自动重新连接(因为已经使用了这些选项)。这是第22条军规的情况。opts.SetConnectRetry(true)
随时随地看视频慕课网APP

相关分类

Go
我要回答