Skip to content

Commit

Permalink
fix: keepalive causes a reconnect loop when connection is lost
Browse files Browse the repository at this point in the history
Fixes #1778
  • Loading branch information
robertsLando committed Jan 23, 2024
1 parent 44a2f2f commit 945c41b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
47 changes: 40 additions & 7 deletions example.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,58 @@
import mqtt from '.'

const client = mqtt.connect('mqtt://test.mosquitto.org')
const client = mqtt.connect('mqtt://test.mosquitto.org', {
keepalive: 10,
reconnectPeriod: 15000,
})

const testTopic = 'presence'

client.subscribe(testTopic, (err) => {
if (!err) {
console.log('subscribed to', testTopic)
client.publish(testTopic, 'Hello mqtt', (err2) => {
function publish() {
client.publish(
testTopic,
`Hello mqtt ${new Date().toISOString()}`,
(err2) => {
if (!err2) {
console.log('message published')
} else {
console.error(err2)
}
})
},
)
}

client.subscribe(testTopic, (err) => {
if (!err) {
console.log('subscribed to', testTopic)
} else {
console.error(err)
}
})

client.on('message', (topic, message) => {
console.log('received message "%s" from topic "%s"', message, topic)
client.end()
setTimeout(() => {
publish()
}, 2000)
})

client.on('error', (err) => {
console.error(err)
})

client.on('connect', () => {
console.log('connected')
publish()
})

client.on('disconnect', () => {
console.log('disconnected')
})

client.on('offline', () => {
console.log('offline')
})

client.on('reconnect', () => {
console.log('reconnect')
})
18 changes: 9 additions & 9 deletions src/lib/PingTimer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,7 @@ export default class PingTimer {
constructor(keepalive: number, checkPing: () => void) {
this.keepalive = keepalive * 1000
this.checkPing = checkPing
this.setup()
}

private setup() {
this.timer = this._setTimeout(() => {
this.checkPing()
this.reschedule()
}, this.keepalive)
this.reschedule()
}

clear() {
Expand All @@ -40,6 +33,13 @@ export default class PingTimer {

reschedule() {
this.clear()
this.setup()
this.timer = this._setTimeout(() => {
this.checkPing()
// prevent possible race condition where the timer is destroyed on _cleauUp
// and recreated here
if (this.timer) {
this.reschedule()
}
}, this.keepalive)
}
}
8 changes: 4 additions & 4 deletions src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ export default class MqttClient extends TypedEventEmitter<MqttClientEventCallbac
clearTimeout(this.connackTimer)

this.log('close :: clearing ping timer')
if (this.pingTimer !== null) {
if (this.pingTimer) {
this.pingTimer.clear()
this.pingTimer = null
}
Expand Down Expand Up @@ -1752,15 +1752,15 @@ export default class MqttClient extends TypedEventEmitter<MqttClientEventCallbac
})
}

if (!this.disconnecting) {
if (!this.disconnecting && !this.reconnecting) {
this.log(
'_cleanUp :: client not disconnecting. Clearing and resetting reconnect.',
'_cleanUp :: client not disconnecting/reconnecting. Clearing and resetting reconnect.',
)
this._clearReconnect()
this._setupReconnect()
}

if (this.pingTimer !== null) {
if (this.pingTimer) {
this.log('_cleanUp :: clearing pingTimer')
this.pingTimer.clear()
this.pingTimer = null
Expand Down

0 comments on commit 945c41b

Please sign in to comment.