fix: 停机先停接受并等待循环再断开 MQTT

This commit is contained in:
Nixevol
2026-09-30 16:22:44 +08:00
parent 6a65ab8593
commit b40ef5c548
8 changed files with 345 additions and 20 deletions
+43 -1
View File
@@ -186,6 +186,7 @@ type mqttSess struct {
inbox []map[string]any
closed bool
done chan struct{}
shutdownCh chan byte
}
type appResp struct {
@@ -201,7 +202,19 @@ func mqttSessionLogin(t *testing.T, httpBase, endpointID, password string) *mqtt
if err != nil {
t.Fatalf("dial: %v", err)
}
s := &mqttSess{t: t, mc: mc, endpointID: endpointID, pktID: 10, done: make(chan struct{})}
s := &mqttSess{t: t, mc: mc, endpointID: endpointID, pktID: 10, done: make(chan struct{}), shutdownCh: make(chan byte, 1)}
s.connectSubscribeHello(password)
go s.readLoop()
return s
}
func mqttSessionLoginTCP(t *testing.T, addr, endpointID, password string) *mqttSess {
t.Helper()
mc, err := harness.DialMQTTTCP(addr, 10*time.Second)
if err != nil {
t.Fatalf("dial tcp: %v", err)
}
s := &mqttSess{t: t, mc: mc, endpointID: endpointID, pktID: 10, done: make(chan struct{}), shutdownCh: make(chan byte, 1)}
s.connectSubscribeHello(password)
go s.readLoop()
return s
@@ -344,6 +357,13 @@ func (s *mqttSess) handlePacket(raw []byte) map[string]any {
switch typ {
case packets.Puback, packets.Pingresp, packets.Suback:
return nil
case packets.Disconnect:
reason := byte(0)
if _, n, err := decodeRemainingLength(raw[1:]); err == nil && 1+n < len(raw) {
reason = raw[1+n]
}
s.noteShutdown(reason)
return nil
case packets.Publish:
payload, err := decodePublishPayload(raw)
if err != nil {
@@ -446,6 +466,28 @@ func (s *mqttSess) takeMatching(pred func(map[string]any) bool) map[string]any {
return nil
}
func (s *mqttSess) noteShutdown(reason byte) {
if s.shutdownCh == nil {
return
}
select {
case s.shutdownCh <- reason:
default:
}
}
func (s *mqttSess) disconnectReason(timeout time.Duration) (byte, bool) {
if s.shutdownCh == nil {
return 0, false
}
select {
case r := <-s.shutdownCh:
return r, true
case <-time.After(timeout):
return 0, false
}
}
func drainEvents(t *testing.T, s *mqttSess, d time.Duration) {
t.Helper()
deadline := time.Now().Add(d)