Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QoS 1 PUBLISH must not be resent during the same connection #491

Closed
HiwayChe opened this issue Jun 11, 2021 · 8 comments
Closed

QoS 1 PUBLISH must not be resent during the same connection #491

HiwayChe opened this issue Jun 11, 2021 · 8 comments
Labels

Comments

@HiwayChe
Copy link

Hi, I am using mqtt-1.2.2.jar as client to sub with broker, my broker is emqx-4.2.2, my iot equipment use mqttV3.1 to pub and my java code use mqttV5 to sub(I don't know if it is ok to use different mqtt version protocol to sub and pub).
Sometimes there will be an error message in log:

2021-06-09 19:29:30.806 [com.hivemq.client.mqtt-10-2] ERROR c.h.c.i.m.h.p.incoming.MqttIncomingQosHandler:51 - QoS 1 PUBLISH (MqttStatefulPublish{stateless=MqttPublish{topic=BGT1/1918BD000186/PeriodReportBin, payload=65byte, qos=AT_LEAST_ONCE, retain=false}, packetIdentifier=419, dup=false, topicAlias=0, subscriptionIdentifiers=[9]}) must not be resent (MqttStatefulPublish{stateless=MqttPublish{topic=BGT1/1918BD000186/PeriodReportBin, payload=65byte, qos=AT_LEAST_ONCE, retain=false}, packetIdentifier=419, dup=true, topicAlias=0, subscriptionIdentifiers=[9]}) during the same connection

I viewed the source code: com.hivemq.client.internal.mqtt.handler.publish.incoming.MqttIncomingQosHandler#readPublishQos1

image

I wonder why QoS 1 PUBLISH must not be resent during the same connection? I did not find detailed message in mqtt5 spec(https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901236).

@LBrandl
Copy link

LBrandl commented Jun 11, 2021

Hi HiwayChe,
If clients with different MQTT versions are supported depends on the broker implementation. I don't know if this is the case for emqx-4.2.2. Since both clients where able to connect, I would assume that it works.
The MQTT 5 spec states under "4.4 Message delivery retry" that:
"When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time"

@HiwayChe
Copy link
Author

Hi @LBrandl,
"When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time"
does it mean that emqx broker should not resend this message to me? is it a bug for emqx broker?

@LBrandl
Copy link

LBrandl commented Jun 11, 2021

The broker should not resend the message to the MQTT v5 client if it doesn't reconnect. Maybe the resend behaviour is configurable. Could be worth checking the broker documentation on that.

@HiwayChe
Copy link
Author

@LBrandl thanks for yr reply. I report this question to emqx https://github.com/emqx/MQTTX/issues/599#issuecomment-859390449, they say:If qos 1 message ack timeout, EMQ X resend message by dup message., it sounds reasonable, and I did not find details about message retry when ack timeout in mqtt spec doc.
It seems coming to a dead end, perhaps what can I do is to subscribe using mqttV3。

@LBrandl
Copy link

LBrandl commented Jun 11, 2021

Timeouts for ACKs are not intended by the MQTT v5 spec, therefore you will not find any details about retries in this case. Both client and broker are not supposed to resend messages if the connection is stable.

@SgtSilvio
Copy link
Member

I close this issue here as this is a bug of emqx.
emqx does not adhere to the MQTT 5 specification regarding the statement Clients and Servers MUST NOT resend messages at any other time because If qos 1 message ack timeout, EMQ X resend message by dup message. violates the specification.
Feel free to comment if something is still unclear.

@HiwayChe
Copy link
Author

HiwayChe commented Jan 6, 2022

@SgtSilvio, if consumer ack timeout or lost on the internet, broker not resend same message to consumer, so how does broker guarantee qos 1 (message must be delivered at least once). From the view of broker, it should resend message if not receive ack, only in this way it can guarantee qos 1 in my opinion.

@manojrawat650
Copy link

I close this issue here as this is a bug of emqx. emqx does not adhere to the MQTT 5 specification regarding the statement Clients and Servers MUST NOT resend messages at any other time because If qos 1 message ack timeout, EMQ X resend message by dup message. violates the specification. Feel free to comment if something is still unclear.

@SgtSilvio, the hivemq client 1.2.2 disconnects with error "QOS1 publish must not be resent during the same connection" if a QOS1 message is resent by the broker in case the message was not acknowledged earlier.
Does it mean that for this to work we will have to disconnect and reconnect on the same session? But according to MQTT spec if we gracefully disconnect a client then the session state will be lost and the broker will not resend the QOS1 message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants