Description
I tested this with mqtt@4.2.1 and node 12.16.3.
Something as simple as this:
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost');
client.on('connect', () => console.log('connected', new Date()));
client.on('close', () => console.log('disconnected', new Date()));
client.on('error', err => console.error('error', err));
setTimeout(() => client.reconnect(), 5000);
Gives this output:
connected 2020-08-28T22:27:42.598Z
disconnected 2020-08-28T22:27:47.606Z
connected 2020-08-28T22:27:47.606Z
disconnected 2020-08-28T22:27:48.611Z
connected 2020-08-28T22:27:48.614Z
disconnected 2020-08-28T22:27:49.616Z
connected 2020-08-28T22:27:49.619Z
disconnected 2020-08-28T22:27:50.621Z
connected 2020-08-28T22:27:50.624Z
disconnected 2020-08-28T22:27:51.625Z
connected 2020-08-28T22:27:51.629Z
I'm going to poke around a little and see if I can't figure out why, but in the meantime I saw that:
- the inner stream emits a
close
event because the Socket was closed - Socket gets closed because a
null
is written to the stream, which looks like that signals the end of the stream. Thenull
is written because some node internals gets anarrayBuffer
ofundefined
insideonStreamRead
... but idk how to debug that any deeper because of async stack traces :/
Metadata
Metadata
Assignees
Labels
No labels
Activity
ferm10n commentedon Aug 28, 2020
I noticed that if I call
.end()
before.reconnect()
, then this issue doesn't happen. That's okay as a workaround I guess. Maybe the resolution to this could be to add a call toend()
before_reconnect()
Odame commentedon Sep 4, 2020
For reference, something like this worked for me.
YoDaMa commentedon Sep 21, 2020
so the issue is that it gets trapped in a reconnect loop? But by calling end and then reconnect, there's no loop, it just reconnects?
ferm10n commentedon Sep 21, 2020
@YoDaMa Yes that's what I saw. You should be able to reproduce it with the snippet at the very top.
YoDaMa commentedon Sep 21, 2020
Posting logs with debugs enabled from the repro:
Looks like the problem is that we do not check if the client is connected or not when reconnecting, and then call
_setupStream
internally, which will reset the stream and emit a close to the client, triggering the infinite reconnect loop. Adding a check if things are connected and calling end if they are seems to fix the problem:fix: check if client connected when reconnecting (#1162)
fix(dependency): Upgrade MQTT.js to fix reconnect bug
fix(dependency): Upgrade MQTT.js to fix reconnect bug