fix: 按 K-00 约定修复 Go SDK 断线重交与退避

This commit is contained in:
Nixevol
2026-09-30 16:24:13 +08:00
parent 3749b9bdf1
commit f6f8ccf269
20 changed files with 1544 additions and 324 deletions
+18 -10
View File
@@ -15,15 +15,15 @@ import (
)
type mqttTransport struct {
mu sync.Mutex
cm *autopaho.ConnectionManager
cancel context.CancelFunc
cfg transportConfig
cred atomic.Value // string
upTopic string
mu sync.Mutex
cm *autopaho.ConnectionManager
cancel context.CancelFunc
cfg transportConfig
cred atomic.Value // string
upTopic string
downTopic string
stopped atomic.Bool
ready chan struct{}
stopped atomic.Bool
ready chan struct{}
}
func newMQTTTransport() *mqttTransport {
@@ -57,7 +57,7 @@ func (t *mqttTransport) Start(ctx context.Context, cfg transportConfig) error {
var sessionExpiry uint32 // 0;由 ConnectPacketBuilder 显式写入 Properties
cliCfg := autopaho.ClientConfig{
ServerUrls: []*url.URL{u},
KeepAlive: 30,
KeepAlive: uint16(DefaultKeepAliveSeconds),
ConnectTimeout: cfg.ConnectTimeout,
CleanStartOnInitialConnection: false, // 不要只靠这个;每次用 ConnectPacketBuilder
SessionExpiryInterval: sessionExpiry,
@@ -75,8 +75,12 @@ func (t *mqttTransport) Start(ctx context.Context, cfg transportConfig) error {
cfg.OnAuthFailed(reason)
}
cancel()
return
}
}
if cfg.Backoff != nil {
cfg.Backoff.MarkOffline()
}
},
OnConnectionDown: func() bool {
if t.stopped.Load() {
@@ -113,14 +117,17 @@ func (t *mqttTransport) Start(ctx context.Context, cfg transportConfig) error {
}()
},
ClientConfig: paho.ClientConfig{
ClientID: cfg.EndpointID,
ClientID: cfg.EndpointID,
PacketTimeout: cfg.ConnectTimeout,
OnServerDisconnect: func(d *paho.Disconnect) {
if d != nil && d.ReasonCode == 0x8E {
if cfg.OnKicked != nil {
cfg.OnKicked()
}
cancel()
return
}
// 0x8B 等其它原因按可重试处理,继续重连。
},
OnPublishReceived: []func(paho.PublishReceived) (bool, error){
func(pr paho.PublishReceived) (bool, error) {
@@ -140,6 +147,7 @@ func (t *mqttTransport) Start(ctx context.Context, cfg transportConfig) error {
c.Properties = &paho.ConnectProperties{}
}
c.Properties.SessionExpiryInterval = &zero
// 不设置 ReceiveMaximum(B-01 / K-00)。
pass, _ := t.cred.Load().(string)
c.UsernameFlag = true
c.Username = cfg.EndpointID