I am using the java api to open a connection to my cloud broker:
I am sending “ping” push messages to keep the connection open indefinitely.
However the connection is closed after seemingly unrelated time spans:
- after 1700 minutes
- after 2897 minutes
Why is that so ? Is there a way to keep the connection by sending push messages in regular intervals ?
Hi @pvittali ,
It is nice that you are interested in MQTT and HiveMQ, please welcome to our community.
Keep alive is not specifically limited on the broker side, it is still 65535, so the broker is not limiting your client’s keepAlive setting in any way.
The MQTT specification says the following:
“The Keep Alive … is the maximum time interval that is permitted to elapse between the point at which the Client finishes transmitting one Control Packet and the point it starts sending the next. It is the responsibility of the Client to ensure that the interval between Control Packets being sent does not exceed the Keep Alive value. In the absence of sending any other Control Packets, the Client MUST send a PINGREQ Packet.”
As long as messages are exchanged frequently and the keep-alive interval is not exceeded, there is no need to send an extra message to establish whether the connection is still open.
If the client does not send a messages during the keep-alive period, it must send a PINGREQ packet to the broker to confirm that it is available and to make sure that the broker is also still available.
The broker must disconnect a client that does not send a message or a PINGREQ packet in one and a half times the keep alive interval. Likewise, the client is expected to close the connection if it does not receive a response from the broker in a reasonable amount of time.
- You indicated that your java api is sending ping push messages – do you mean, PINGREQ packets? If so, does your client receive PINGRESP is response from the broker, or it stops at some point and then the client is offline?
- Does you client receive or send a DISCONNECT from the broker? Is it a graceful disconnect or ungraceful one?
- You indicated you use a java api – which api it is, is it HiveMQ MQTT Client Java API or a different one?
- What’s your client’s MQTT version: MQTT v.3, v.3.1.1 or v.5?
- What kind of network your client works in, e.g. ethernet or LTE, etc.?
Dasha from HiveMQ team
Thanks a lot for the feedback and the questions:
- the “ping” message I refered to is just a regular publishWith().topic(…) call.
- implementation ‘com.hivemq:hivemq-mqtt-client:1.2.2’ → yes its the hivemq api, v 1.2.2
- I am using the MQTT v 5 version of your api
- network is a very reliable ethernet / optical cable (on the public side) with no wireless links.
- the error I receive, is that when I try to publish, I get a “connection closed” error.
thanks for providing more details regarding your issue. As far as I understand from your description:
- the client connects to the HiveMQ Cloud cluster;
- the client is inactive for some time (1700 - 2897 minutes)
- then the client attempts to publish a message, that fails and results in a DISCONNECT from the broker
Is my understanding correct? If so, can you perhaps check with WireShark, whether the client is keeping the connection alive by sending PINGREQ packets to the broker from time to time?
Dasha from HiveMQ
I am sorry , I wasn’t clear: I send a publish request every minute. Then after a varying number of such requests, the request #1700 or #2897, (or some seemingly random number) the subsequent request will fail. This is the error message:
com.hivemq.client.mqtt.exceptions.MqttClientStateException: MQTT client is not connected.
This means that connection has been closed for example in between minute 1699 and 1700 after opening the connection.
What could be the reasons for this ?
@pvittali , thanks for providing more info regarding the issue. Could you please let me know, what type of cluster in the HiveMQ cloud it is. You can check this in you cloud.hivemq.com account. for example, I have a Free cluster:
What cluster type do you have?
Hi @pvittali ,
Thank you for providing more details. I see following possible reasons for the disconnection and the subsequent message:
- Broker fails the publish because the number of available connections to the cluster is reached or all available traffic used. – This is a low probability, as you say you have only 1 client connection, messages are only 1 per minute, the size is probably also small.
- A network error – which from experience has 99% probability.
If your client can reconnect after the disconnection and publish messages successfully – then the reason #1 is not the case. To work around the issue you could simply make your client reconnect again.
For deeper analysis we would need to see your code. Feel free to share your project and if you do, please specify up to which point it runs correctly and where it fails).
Thanks for the explanation.
I can rewrite the code to try to reconnect and then I will find out if #1 is the case.
But more importantly, I think I had a misconception about the MQTT protocol. I somehow thought that
the protocol ensures that the connection survives network errors. This seems to be wrong: even a network problem can disrupt the connection in which case I have to manually reconnect. Is this the case ?
Just for the record: I just discovered
in the client api. This is exactly what I was looking for ( rather than writing my own reconnect code.
Thanks again for your time
great @pvittali , thank you for the update! There is also an example on implementing a custom Reconnect Strategy that you might also find helpful: hivemq-mqtt-client/ReconnectStrategy.java at master · hivemq/hivemq-mqtt-client · GitHub