为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
HUWWW 2022-09-05 09:46:06
我想确保我的程序在无法连接到MQTT服务器时崩溃。为此,我将ConnectTimeout设置为10秒,但是当连接到不存在的服务器(名称不存在)时,对MQTT的调用挂起。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.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()))    }}如何正确设置超时?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

来自 SetConnectRetry 的文档:


SetConnectRetry 设置连接函数在发生故障时是否会自动重试连接(如果为 true,则 Connect 函数返回的令牌在连接启动或取消之前不会完成)如果 ConnectRetry 为 true,则应在 OnConnect 处理程序中请求订阅 如果设置为 TRUE,则允许在建立连接之前发布消息。


因此,何时将重试,直到成功或您停止它。不会尝试确定错误是否是永久性的,因为这非常困难(例如,无法解决可能是由于互联网连接丢失)。SetConnectRetry(true)Connect()this.does.not.resolve.example.coooom


注意:有一个单独的选项,用于控制断开的连接(在成功建立初始连接后)是否会导致客户端自动重新建立连接。SetAutoReconnect


值得注意的是,添加该选项的主要原因是允许用户在连接启动之前发布消息(当建立连接时,它们将自动发送)。这个想法是,您应该能够调用然后使用库,而不必担心网络状态(显然,如果网络出现故障,您将不会收到消息!ConnectRetryConnect


SetConnectTimeout文档在如何与以下各项交互方面可能并不像它们应该的那样清晰:SetConnectRetry


SetConnectTimeout 限制客户端在超时之前尝试打开与 MQTT 服务器的连接时将等待的时间。持续时间 0 永远不会超时。默认值为 30 秒。目前仅在 TCP/TLS 连接上运行。


因此,这控制了我们将等待单个连接尝试完成的时间。每次尝试连接时将使用此间隔(每次尝试时重新开始)。没有类型设置。SetConnectRetry (true)RetryConnectionsFor


来自自我回答:


...连接正确失败(并且,如果连接断开,客户端仍将重新连接)


一旦调用了选项,就无法更改选项(获取选项的副本)。它之所以这样做,是因为在操作过程中更改选项将导致不可预测的结果(例如,如果您在调用后调用,则结果将取决于调用是否已完成,这是不可预测的)。NewClient(o *ClientOptions)NewClientopts.SetConnectRetry(true)ConnectConnect


我不太确定你所说的“确保我的程序崩溃,如果它无法连接到MQTT服务器”是什么意思,但我使用的方法是如下(用适当的操作代替语句) - 请注意,我还没有编译/测试这个:fmt.PrintLn


package main


import (

    "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

}


查看完整回答
反对 回复 2022-09-05
?
临摹微笑

TA贡献1982条经验 获得超2个赞

opts.SetConnectRetry(true)似乎将连接放在循环中(没有任何错误消息)。通过将代码更改为 ...


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.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)


查看完整回答
反对 回复 2022-09-05
  • 2 回答
  • 0 关注
  • 1738 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信