how to make client send a disconnect packet?
In some tests I'm writing I need to make clients voluntarily disconnect, and reconnect later when I tell them to, with same clientId and session resending any QoS 1/2 messages.
Oddly it seems like there's no way to do this....end() seems rather permanent and calling .reconnect() afterwards doesn't seem to do anything.
I have a app that have to publish to everyone that it are disconnecting. This is the way I do it:
cli.publish('topic', 'disconnected', 0, {}, () => {cli.end()})
I put this snippet in an disconnect function. Is this what you need?
@jedwards1211 See the following test case: https://github.com/mqttjs/MQTT.js/blob/4bd3f3c7e0180646e38d2acc490d511c0547e556/test/abstract_client.js#L2825-L2869
incomingStore and outgoingStore can be passed from the outside of the client. And they have clean flag. If it set false, then the Store doesn't clean if the client calls the end(). So the QoS 1/2 messages are preserved after end() is called.
https://github.com/mqttjs/MQTT.js/blob/4bd3f3c7e0180646e38d2acc490d511c0547e556/test/abstract_client.js#L2828-L2829
When the first client connection, set clean: false and incomingStore and outgoingStore.
https://github.com/mqttjs/MQTT.js/blob/4bd3f3c7e0180646e38d2acc490d511c0547e556/test/abstract_client.js#L2852-L2860
When you want to disconnect from the client side using DISCONNECT packet, you can call end() as follows: https://github.com/mqttjs/MQTT.js/blob/4bd3f3c7e0180646e38d2acc490d511c0547e556/test/abstract_client.js#L2840-L2846
In this case, client.reconnect() is called just after end() process is finished. But you can call reconnect anywhere.
The important point is passing incomingStore and outgoingStore as the reconnect argument.
Alternative approach:
You can create the new client instead of calling reconnect().
The key is managing incomingStore and outgoingStore by yourself at the outside of the client.
The test case code set force option true when end() calling. https://github.com/mqttjs/MQTT.js/blob/4bd3f3c7e0180646e38d2acc490d511c0547e556/test/abstract_client.js#L2840 In order to send DISCONNECT packet, you need to set force flag to false. https://github.com/mqttjs/MQTT.js/blob/d8be59eba419d65ad2f46734623fd91ec437d6e2/lib/client.js#L861 https://github.com/mqttjs/MQTT.js/blob/d8be59eba419d65ad2f46734623fd91ec437d6e2/lib/client.js#L911 https://github.com/mqttjs/MQTT.js/blob/d8be59eba419d65ad2f46734623fd91ec437d6e2/lib/client.js#L1050-L1074
See also #706 and #707.
@redboltz Thanks for your examples.
As I mentioned in https://github.com/mqttjs/MQTT.js/issues/1286#issuecomment-855263741, I think it would be better not to store a clean flag on the stores and instead have the client tell the stores whether to discard state when the client is shutting down. It's counterintuitive that passing clean: false in the connect options isn't enough.
Ah, I just realized that you are the person who create the issue #1286. I understand. I think that the current status is we have a way to send disconnect and reconnect with preserving stores but it is not intuitive. So there is no defect in the behavior but there is a room to improve. Is that right?
Right, I wasn't saying there's any incorrect behavior
@redboltz do you think you could summarize this under the vNext discussion? https://github.com/mqttjs/MQTT.js/discussions/1324
The policy seems clunky right now, and I agree there's room for improvement.
This is an automated message to let you know that this issue has gone 365 days without any activity. In order to ensure that we work on issues that still matter, this issue will be closed in 14 days.
If this issue is still important, you can simply comment with a "bump" to keep it open.
Thank you for your contribution.
This issue was automatically closed due to inactivity.