robocar-steering/vendor/github.com/eclipse/paho.mqtt.golang/ping.go

79 lines
2.5 KiB
Go
Raw Normal View History

2020-02-08 21:35:47 +00:00
/*
2022-06-09 13:59:30 +00:00
* Copyright (c) 2021 IBM Corp and others.
2020-02-08 21:35:47 +00:00
*
* All rights reserved. This program and the accompanying materials
2022-06-09 13:59:30 +00:00
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
2020-02-08 21:35:47 +00:00
*
* Contributors:
* Seth Hoenig
* Allan Stockdill-Mander
* Mike Robertson
*/
package mqtt
import (
"errors"
"io"
2020-02-08 21:35:47 +00:00
"sync/atomic"
"time"
"github.com/eclipse/paho.mqtt.golang/packets"
)
// keepalive - Send ping when connection unused for set period
// connection passed in to avoid race condition on shutdown
func keepalive(c *client, conn io.Writer) {
2020-02-08 21:35:47 +00:00
defer c.workers.Done()
DEBUG.Println(PNG, "keepalive starting")
2023-10-15 09:51:11 +00:00
var checkInterval time.Duration
2020-02-08 21:35:47 +00:00
var pingSent time.Time
if c.options.KeepAlive > 10 {
2023-10-15 09:51:11 +00:00
checkInterval = 5 * time.Second
2020-02-08 21:35:47 +00:00
} else {
2023-10-15 09:51:11 +00:00
checkInterval = time.Duration(c.options.KeepAlive) * time.Second / 2
2020-02-08 21:35:47 +00:00
}
2023-10-15 09:51:11 +00:00
intervalTicker := time.NewTicker(checkInterval)
2020-02-08 21:35:47 +00:00
defer intervalTicker.Stop()
for {
select {
case <-c.stop:
DEBUG.Println(PNG, "keepalive stopped")
return
case <-intervalTicker.C:
lastSent := c.lastSent.Load().(time.Time)
lastReceived := c.lastReceived.Load().(time.Time)
DEBUG.Println(PNG, "ping check", time.Since(lastSent).Seconds())
if time.Since(lastSent) >= time.Duration(c.options.KeepAlive*int64(time.Second)) || time.Since(lastReceived) >= time.Duration(c.options.KeepAlive*int64(time.Second)) {
if atomic.LoadInt32(&c.pingOutstanding) == 0 {
DEBUG.Println(PNG, "keepalive sending ping")
ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket)
2023-10-15 09:51:11 +00:00
// We don't want to wait behind large messages being sent, the `Write` call
// will block until it is able to send the packet.
2020-02-08 21:35:47 +00:00
atomic.StoreInt32(&c.pingOutstanding, 1)
if err := ping.Write(conn); err != nil {
ERROR.Println(PNG, err)
}
2020-02-08 21:35:47 +00:00
c.lastSent.Store(time.Now())
pingSent = time.Now()
}
}
if atomic.LoadInt32(&c.pingOutstanding) > 0 && time.Since(pingSent) >= c.options.PingTimeout {
2020-02-08 21:35:47 +00:00
CRITICAL.Println(PNG, "pingresp not received, disconnecting")
c.internalConnLost(errors.New("pingresp not received, disconnecting")) // no harm in calling this if the connection is already down (or shutdown is in progress)
2020-02-08 21:35:47 +00:00
return
}
}
}
}